Repository navigation
Release OpenSPP v4 - #1805
Merged
Merged
Release OpenSPP v4#1805
Conversation
OpenSPP2 runs on Odoo 19, which deprecates JSON-RPC (removal is scheduled for Odoo 20), and JSON-RPC bypasses spp_api_v2's consent, scopes and audit. v4 talks to /api/v2/spp with OAuth2 client credentials instead. - Replace odoo-await with the common request helper; add Utils.js (token once per run, tolerant error parsing, identifier encoding, search result unwrapping for SearchResult and FHIR Bundle responses) - Keep the v1 operation names; drop getArea/searchArea (no Area resource) and callbacks; operations now throw on errors - Identifiers are system|value; membership functions take typed Individual/ or Group/ references - Guard enroll/unenroll against OpenSPP2 resolving memberships by beneficiary only, and check a group exists before group searches (OpenSPP/OpenSPP2#554) - MockAgent unit tests for every operation and helper - Major changeset with a v3 to v4 migration guide
- Move private helpers (assert*, read/search/create/patchResource, listMemberships, findMembership, putMembership) to Utils.js - Throw on v3 Odoo domain queries, which OpenSPP ignored and so returned every record - Throw on v3 limit/order options (use count/sort) instead of silently dropping them - getPrograms takes one options object; throw on offset/limit/order since programs only page with a cursor - Inline the membership role system; drop header notes and link the REST API v2 reference from the README - Add paging before/after examples to the migration guide
Add a per-function scope and module table (the old example scope group:search is not what searches check), paging rules with a loop that follows page.next, and an errors section. Fix sort examples to use birthDate: OpenSPP falls back to name for unknown sort fields, so -birthdate sorted by name.
… 2026.09 Following the next link can skip records under consent filtering (fetch_with_consent advances past the whole over-fetched batch), so the paging example now steps offset by count and de-duplicates. Create does not return 409 for a used identifier on 2026.09, missing individuals/groups return 403 for consent-requiring clients, and only the token endpoint is rate limited (5/min, 50/day). Scope table lists search alternatives and group:read for group filters.
…nores OpenSPP sorts individuals by name for any sort value other than name, birthDate or lastUpdated, and /ServicePoint drops _sort, _lastId, _elements and _extensions, so these now throw instead of returning silently different results.
…SPP2 2026.09 OpenSPP2 2026.09 matches group and membership-role against any membership, ignores unknown role codes and unresolvable member filters (returning every record), replaces roles on addToGroup, and does not store removeFromGroup reason or unenroll exitReason. The 403 hint now reflects that not-found returns 403 only for consent-requiring clients.
OpenSPP caps each search query at 100 rows, so with count above 50 consent-hidden records end paging early (at 100, one hidden record does): recommend count 50. Credit open PR #555 only with what it fixes (group former members, stale removed status, member references, per-program memberships), not the group/role cross-match. Tokens are fetched once per workflow step, not per run.
Clarify that the adaptor still refuses multi-program membership updates on #555, give the exact early-end threshold for count above 50, version-qualify the member and role notes, and skip records without identifiers in the paging example.
…mber OpenSPP2 #555 also returns 409 for an identifier that matches more than one registrant; treating every 409 as an existing member sent a PATCH that failed with a misleading error. Test fixtures now use a real role code and the startDate/active|inactive shapes OpenSPP returns.
Open PR #555 now fixes consent paging (next no longer skips, short pages keep next), requires the role on the same group membership, rejects unknown role codes with 422, fixes PATCH gender, and returns 403 instead of 500 for getPrograms without scope. Notes say which behaviour is 2026.09 and which is #555.
Documents the getPrograms filters and cursor paging as a typedef, as asked in review. lastId accepts a number or the string from the next link.
… options offset and limit point to the count/lastId cursor, while order says programs cannot be sorted, instead of one message that told order users to set a page size.
…the response As asked in review, the Utils helper no longer returns an operation or resolves references. Each search operation in Adaptor.js resolves its own query and options and calls prepareSearchState.
…tion Utils.js now has no helpers that return operations or resolve references, matching the searchResource change. getIndividual, getGroup, getProgram, createIndividual, createGroup, updateIndividual and updateGroup resolve their own arguments and call prepareNextState.
Document the one-head rule, #570 (removed members cannot be re-added, and 2026.09 reports the ended membership instead of failing), enroll failing when a membership is hidden, unresolvable references and the loose identifier filter on 2026.09, and #555 behaviour for shared identifiers in search filters. Correct the early-end threshold, the stepping claim, the ifMatch scope, the per-process rate-limit counter and the addToGroup 409 comment.
OpenSPP checks one head per group in an onchange handler, which only runs in its forms; the API accepts a second head on 2026.09 and on #555 (checked live).
The per-page read limit is 3 x count for count up to 50 and 100 above that; #570 on 2026.09 only returns the ended membership until the membership repair runs; shared-identifier filters make enroll fail with 403 and unenroll with "is not a member"; 409 with ifMatch can also mean a shared identifier on #555; stepping by count is exact for individuals.
Add shared test helpers: createMockServer captures common's mock client log line, assertAllMocksUsed fails a test with unused interceptors, and jsonBody returns false on a mismatch as undici expects instead of throwing, which broke unrelated requests after a query-string match. runWithState replaces the fn() setup step, and each run mocks exactly one token response.
Rename tests whose names claimed checks they didn't make, assert full error messages, and add tests for startDate, endedDate, enrollmentDate, exitReason, object roles, If-Match, paged memberships and the membership helpers. Every deliberate source mutation in the check now fails the suite.
Options such as sort on groups, lastId outside programs, v3 limit and order, and unknown sort fields now log a warning and the job carries on. Filters that OpenSPP would drop, returning every record, still throw. The create identifier check is removed: OpenSPP already rejects it with 422.
addToGroup no longer falls back to a PATCH on OpenSPP's 409, which relied on the wording of its error. It sends one request and surfaces the 409; role changes go through request.
Public docs no longer track OpenSPP releases or upstream pull requests, and the paging walkthrough is removed. Search parameters and resource fields link to the OpenSPP API docs. The AI directive comment blocks are removed.
State what enroll and unenroll return when nothing changes, that unenroll throws without a membership, that OpenSPP doesn't save reason or exitReason, and that a role change through request needs a CodeableConcept.
jsdoc2md renders parameters as markdown table rows, where an unescaped pipe inside system|value split the cell and cut off the value.
feat(openspp): rebuild adaptor on the OpenSPP2 REST API v2 (4.0.0)
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.
Release branch for #1792