feat: p2p wifi hotspot sync - server apis and webapp integration - #10893
Open
paulpascal wants to merge 15 commits into
Open
feat: p2p wifi hotspot sync - server apis and webapp integration#10893paulpascal wants to merge 15 commits into
paulpascal wants to merge 15 commits into
Conversation
…ization service (medic#10799) Signed-off-by: Diana Barsan <barsan@medic.org>
…dic#10811) (cherry picked from commit 6a5867b) medic#10802 Co-authored-by: 1yuv <yrimal@outlook.com>
closes medic#10779 (cherry picked from commit f07a592)
Wave 1 server APIs: POST /api/v1/p2p/authorize (JWT issuance), GET /api/v1/p2p/config/:facility_id, POST /api/v1/p2p/telemetry, GET /api/v1/p2p/revocation-list, scope-manifest generator. Route registration in api/src/routing.js. Full test coverage.
Wave 3 webapp: Angular P2P module with status and history components. P2P config service, transit filter service (excludes transit docs from UI), transit purge service (uses db.purge, never db.remove). P2P styles.
…ations) Wave 3 integration: inject transit filter into contacts, search, rules-engine, and target-aggregates services. Pause/resume replication during P2P sync in db-sync service. Add P2P bridge methods to android-api service. P2P sidebar menu entry and route. Translation strings for all P2P UI elements.
The authorize endpoint was checking a non-existent allowed_roles field, falling back to hardcoded ['chw', 'chw_supervisor']. This caused 403 for any deployment using different role names. Now reads host_roles and peer_roles from p2p_sync config. Default fallbacks changed to empty arrays — if roles are not configured, P2P simply does not activate.
- Add P2P menu item to old nav header dropdown (header.component) - Add &.p2p to old-nav.less page list for proper padding - Add wrapper div in P2P templates to match About page card layout - Show sync history only on peer (CHW) side
Update test expectations after removing hardcoded role defaults. Tests now use host_roles/peer_roles instead of allowed_roles.
- Add curly braces to single-line if statements - Rename unused catch vars to _e/_err pattern - Break long lines (max 120 chars) - Use array.includes() for isSyncing check
- Use node:crypto imports (S7772) - Reduce cognitive complexity by extracting helpers (S3776) - Use optional chaining (S6582) - Use Set for role lookups (S7776) - Flip negated ternary conditions (S7735) - Name arrow function export (S7726) - Mark injected services as readonly (S2933) - Add logging in catch blocks (S2486) - Replace display-only <label> with <span> for accessibility (S6853) - Extract type aliases and constants (S4323, S1192)
- Reduce cognitive complexity in transit-purge, transit-filter, p2p-status, and db-sync by extracting helpers (S3776) - Mark services as readonly (S2933) - Flip negated conditions in p2p-config (S7735) - Use optional chaining and direct undefined comparison (S6582, S7741) - Replace Promise.resolve() with direct return (S7746) - Remove 'any' from union types (S6571) - Add logging in empty catch blocks (S2486)
Add mock providers for P2pConfigService, P2pTransitFilterService, and P2pTransitPurgeService to test files that instantiate services where P2P dependencies were injected. Mocks return safe defaults (P2P disabled, no transit docs) so existing tests pass unchanged.
paulpascal
force-pushed
the
feat/p2p-sync
branch
6 times, most recently
from
April 18, 2026 22:34
e8705d7 to
37261a8
Compare
- Extract isP2pPausingSync helper from shouldSkipSync (S3776) - Extract purgeOneDoc helper from purgeDocBatch (S3776) - Return fresh object literals in purgeConfirmedTransitDocs (S3516) - Extract handleQrScanResult from callback (S3776) - Extract executePostP2pSyncAttempt and retryPostP2pSyncIfPossible (S3776)
paulpascal
force-pushed
the
feat/p2p-sync
branch
from
April 18, 2026 23:40
37261a8 to
dcb9e0f
Compare
Contributor
|
wow!! what an epic PR @paulpascal - impressive!! I've added back in a Thanks! |
Contributor
Author
|
Thanks @mrjones-plip , well noted, will promptly updated the checklist accordingly |
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.
Summary
Adds P2P WiFi Hotspot sync capability to CHT, enabling CHWs in offline areas to push health data to a Supervisor's phone over a local WiFi connection. The Supervisor relays data to the msain server on next online sync.
This PR covers the server-side APIs and webapp integration. The related Android PR is at medic/cht-android#431.
What's included
Server API endpoints (
api/src/p2p/):POST /api/v1/p2p/authorize: Issues JWT token with ECDSA P-256 for offline device authenticationGET /api/v1/p2p/config/:facility_id: Returns P2P configuration for a facilityGET /api/v1/p2p/revocation-list: Returns revoked devices/usersPOST /api/v1/p2p/telemetry: Receives session telemetry (fire-and-forget)Webapp P2P module (
webapp/src/ts/modules/p2p/):p2p_syncfrom app_settingsKey design decisions:
host_rolesandpeer_rolesin app_settings : no hardcoded role names_deleted: true+purged: true) with replication filter, notdb.remove()which would create destructive tombstonesnew_edits: falsefor automatic CouchDB deduplicationEg. of configuration:
{ "p2p_sync": { "enabled": true, "host_roles": ["supervisor"], "peer_roles": ["chw"] } }Files changed
Test plan
npx mocha api/tests/p2p/**/*.spec.jsCode review checklist
can_view_old_navigationpermission to see the old design. Test it has appropriate design for RTL languages.License
The software is provided under AGPL-3.0. Contributions to this project are accepted under the same license.