Repository navigation
Conversation
🛡️ Trivy security scan (CRITICAL,HIGH,MEDIUM,LOW)Go dependencies
Container image
|
|
📊 Test Coverage: ✅ Passed — 92% of changed lines covered, min 80% |
ameersohel45
reviewed
Oct 9, 2026
ameersohel45
reviewed
Oct 9, 2026
ameersohel45
reviewed
Oct 9, 2026
ameersohel45
reviewed
Oct 9, 2026
ameersohel45
reviewed
Oct 9, 2026
nisargabd
added a commit
that referenced
this pull request
Oct 10, 2026
- An empty or all-null PMFBY record is no record (202), not a grievance reported as under review. - cropYear must be a four-digit year: PMFBY reads requestYear like the ids. - A mapping writing "_error": null means no error, not a 500. - BindingPaths refuses a path list, so a caller reading one pair fails at startup instead of matching nothing.
This was referenced Oct 12, 2026
…ecks [#57] Some upstreams, PMFBY among them, answer every call with a 200 and signal failure in the body. Without a way to recognise that, the response half mapped a refusal as if it were an answer. A mapping file can now declare a reject section, checked after the call and before the response half runs, and any check can carry its own error code and HTTP status. The step uses Reject only when the mapper offers it, so existing mappers and plugins need no change, and a check without a code keeps returning the generic bad-request code it did before.
…token [#57] PMFBY issues a token from its own login endpoint and expects it back, unprefixed, in the Authorization header. tokenQuery already does that login but puts the token in the query string, and oauth2 sends it as a Bearer header, so neither fits. tokenHeader reuses tokenQuery's exchange, caching and redaction and places the token in a configured header, which keeps PMFBY's auth config-only.
…ppings [#57] Farmers need to file a PMFBY grievance and check on it. The plugin is a thin package over the shared step, like MandiPrice, and holds no PMFBY logic: init sends an OTP, confirm files the grievance with it, and status reads the ticket back, all described by the mapping files. The mappings follow the PMFBY Postman collection for the ticket and status calls (AddKRPHNCIPGrievenceSupportTicket, receiptSourceID) and the design doc for the OTP step, which the collection does not cover yet. The OTP is never echoed, and the status answer is an allow-list that drops the farmer's personal details.
…he OTP is sent [#57] A refusal carrying "responseMessage": null passed the $exists guard and then failed inside $lowercase, so the caller got a 400 adaptation error instead of the 502 a portal refusal should be. Only a string message is now read for "otp". A phone sent as a number passed the presence check, PMFBY sent the OTP, and only then did the reply fail to mask it, so a retry would send a second OTP. init now refuses a non-string phone before calling PMFBY.
…er [#57] The reject path logged the provider's raw answer at WARN with only credentials redacted, and PMFBY refusals can echo the farmer's phone number or other personal details. The log now carries the mapping's own message, which says what was refused without quoting the provider.
The exchange now serves tokenHeader as well as tokenQuery, so a name tied to the query placement misled readers about what calls it.
…ping "null" [#57] A status record with "TicketStatus": null failed the whole call in $replace, so the farmer could not read their ticket at all. A null category name or sub-category id came back as "null / ..." or "3.null", and a null description, date or remark was returned as JSON null. Each field is now mapped only when it holds a real value and dropped otherwise, so one missing field no longer costs the rest of the answer.
…57] The updated grievance design lodges with support, and a SupportAction composes no contract: there is no offer to read the provider from and no commitment to read the type from, so the step passed every support request through unserved. A step can now name a second pair of paths, tried only when the first finds nothing. Grievance sets it to message.support.channels[].providerId and .@type, where the design places them. Both or neither, as with the first pair, and plugins that set neither behave as before.
…igned [#57] The grievance design moved lodging from confirm to support and fixed the replies and errors each action returns. The mappings follow it: support reads the application number from orderId, the complaint from descriptor and the farmer from channels[0]; status puts the complaint on contract.descriptor and the case record in the attributes. The error table needs answers the mapper cannot give, and the mapper stays unchanged: the reject section and Reject hook are removed from jsonmapper. Instead a mapping half may return a reserved _error object, which the step turns into the reply: - a missing field is refused by the request half with SCH_REQUIRED_FIELD_MISSING, before PMFBY is called - a status reply with no case record is a 202 ACK, BIZ_NO_RESULTS_FOUND - a 4xx from the provider keeps its status and is shown to the response half under _status; support reads PMFBY's 400 as a wrong OTP and answers 400 BIZ_GENERIC_ERROR, and anything a mapping does not explain stays 502 Nothing is read from a failure body: PMFBY's failure format is not documented. SendOTP's reply is not either, so on_init carries no expiresAt.
…ecode each payload once [#57]
…#57] A support request names its provider and type on its channel rather than on a contract. Saying where they sit per action, in config, replaces the fallback pair: a later action, or a schema that moves the fields, is a config edit.
New already validates every action's paths and refuses an empty one, so the parser checking both halves again was a second copy of the same rule.
providerIdAt and capabilityCodeAt may each list several paths, paired by position and tried in order. A support request is found on its channel by the second pair, so no action-keyed block, no parser for it and no change to the plugin's config parsing are needed. A single path behaves as before.
tokenHeader reuses the tokenQuery exchange unchanged, so its name and the redaction comment need no rewrite; only the scheme check and the token path differ.
- An empty or all-null PMFBY record is no record (202), not a grievance reported as under review. - cropYear must be a four-digit year: PMFBY reads requestYear like the ids. - A mapping writing "_error": null means no error, not a 500. - BindingPaths refuses a path list, so a caller reading one pair fails at startup instead of matching nothing.
…ounds [#57] The pack now refuses case.status.name: the portal's TicketStatus picks the code and is not forwarded. And the implementation doc restates enrolmentId's 10-30 character bound on support, where it rides in orderId outside the channel the pack validates.
…nel [#57] The use case doc makes the category codes optional, defaulting to PMFBY's published 3 and 10, and the pack keeps enrolmentId in the channel instead of message.support.orderId.
nisargabd
force-pushed
the
feat/57-pmfby-grievance-plugin
branch
from
October 13, 2026 06:09
9185726 to
9dec9bb
Compare
…#57] PMFBY answers every call with HTTP 200, so a refusal was reported as a 502 with our own text, hiding the reason the caller can act on. A refusal with a reason is now a 400 carrying PMFBY's message; a reply with no reason is a 502, since that is PMFBY failing rather than the caller. Format checks move out of the mappings to the pack, and filedOn becomes a UTC instant.
PMFBY's login states when its token expires, so a configured tokenTtl was a guess at a number the issuer already gives. tokenExpiryField reads it from the reply instead; tokenTtl stays for issuers that state none.
PMFBY's expirationTime is the moment a token was issued, not when it expires, so every token read as already expired and every call failed. validTo is the expiry, as an RFC 3339 time, so tokenExpiryField now reads that form as well as Unix seconds.
The demo portal sends InsertDateTime as "2026-10-12T11:02:49.000Z", not the bare IST time the mapping expected, so filedOn was always dropped on a read.
PMFBY answers every failure with HTTP 200 and responseCode "0", so the mapping passed its message straight to the caller: an internal "AxiosError: Request failed with status code 403" reached the farmer as a 400, as if the request were wrong. The contract says the portal's own message is never forwarded. A refusal PMFBY is known to give is now a 400 in our words; any other failure is a 502 asking the caller to try again later. PMFBY's text rides on _error.cause into the warning log and is never returned.
… status fields [#57] The separate PMFBYGrievance pack is gone: PMFBY is now the PMFBY branch of Grievance/v0.1, picked by scheme.code, under @type openagrinet:Grievance. The binding key, the request's applicantPhone (now applicantMobile) and the fixtures follow it. The pack's status read now lists what PMFBY's record really carries, so the mapping returns cropYear, season (1/2/3 as Kharif/Rabi/Zaid), the category and sub-category codes beside their names, and case.reply from latestRemark. PMFBY's 0 for "none", out-of-range values and blank remarks are dropped rather than sent as values the pack refuses.
PMFBY's "Open" is a ticket nobody has acted on yet, which is Registered, not UnderReview; it is still not final, so an unknown phrase keeps falling to UnderReview. The lodge reply took filedOn from the caller's complaintDate while the status read takes it from PMFBY's InsertDateTime, so a back-dated complaint showed two filing times for one ticket. filedOn is now the lodge time on both; complaintDate still goes to PMFBY as its IST date.
nisargabd
force-pushed
the
feat/57-pmfby-grievance-plugin
branch
from
October 19, 2026 05:37
83f9f40 to
c604cb0
Compare
The Grievance pack now enforces its mustSend lists, so the schema validator refuses a support or status call missing a required field before the mapping runs. The mappings' own $missing checks could no longer fire, so they and their tests are removed.
manjudr
added this pull request to stack #87
October 22, 2026 06:40
manjudr
reviewed
Oct 22, 2026
manjudr
reviewed
Oct 22, 2026
manjudr
reviewed
Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a Grievance plugin so a farmer can file a PMFBY crop-insurance grievance and check its status over Beckn, following the
Grievance/v0.1schema pack.supportfiles the grievance with PMFBY and returns the ticket number.statusreads the grievance back by ticket number and phone. It returns the status, category, crop year, season, crop and PMFBY's reply, and drops the farmer's personal details.Openis returned asRegistered,ResolvedasResolved, and anything else asUnderReview.400. Any other PMFBY failure is a502. PMFBY's own message is logged, never returned.Why
Farmers need to raise and track PMFBY grievances through the network. PMFBY answers every call with HTTP 200, even failures, so the adapter has to read each reply to tell the caller what went wrong.
Testing
Unit tests run the real mappings against a PMFBY stub. End to end, the flow was run on the quick-start stack against PMFBY's demo portal, and the other capabilities behave as before.
Known gaps
anyOf, and a failedanyOfcannot say which field caused it. The fix is in the pack (the same rules written asoneOf).OpenandResolvedare provisional until PMFBY publishes its list.Related: OpenAgriNet/helmcharts#78 (quick-start, charts, mock).
Checklist
Closes #57