Skip to content

feat: anomaly alerting, pagination, correlation IDs, multi-dose support (#23 #27 #115 #119)#206

Merged
dev-fatima-24 merged 2 commits into
dev-fatima-24:mainfrom
kelly-musk:feat/issues-23-27-115-119
Apr 29, 2026
Merged

feat: anomaly alerting, pagination, correlation IDs, multi-dose support (#23 #27 #115 #119)#206
dev-fatima-24 merged 2 commits into
dev-fatima-24:mainfrom
kelly-musk:feat/issues-23-27-115-119

Conversation

@kelly-musk
Copy link
Copy Markdown
Contributor

@kelly-musk kelly-musk commented Apr 29, 2026

Closes #27


Closes #115


Closes #23


Closes #119


Summary

Implements four issues in a single branch.


#115 — Anomaly detection alerting

  • python-service/alerting.py: dispatch_alerts() sends one webhook POST per flagged issuer. Supports Slack, PagerDuty, and email payload formats.
  • python-service/scheduler.py: APScheduler AsyncIOScheduler runs the anomaly check on a configurable interval (ANOMALY_SCHEDULE_MINUTES, default 15).
  • python-service/main.py: FastAPI lifespan context manager starts/stops the scheduler.
  • python-service/requirements.txt: added apscheduler==3.10.4.
  • Alert payload includes: issuer address, anomaly type (high_mint_volume), record count, ISO-8601 timestamp.
  • New env vars: ALERT_WEBHOOK_URL, ALERT_WEBHOOK_TYPE, PAGERDUTY_ROUTING_KEY, ALERT_EMAIL_TO, ANOMALY_SCHEDULE_MINUTES.
  • 9 new tests in tests/test_alerting_scheduler.py (all passing).

#27 — Paginate GET /vaccination/:wallet

  • Endpoint accepts ?page (default 1) and ?limit (default 20, max 100); returns 400 for invalid values.
  • Response shape: { data: [], total, page, limit }.
  • useVaccination.fetchRecords(wallet, { page, limit }) forwards params to the API.
  • PatientDashboard replaced client-side usePagination with server-side pagination state; page changes trigger a new fetch.
  • Also fixed pre-existing bugs: missing eventsRoutes import in app.js, secrets.js ESM mock for Jest, invalid wallet address in integration tests, duplicate keys in frontend/package.json.

#23 — Structured logging with request correlation IDs

  • backend/src/middleware/requestId.js: echoes client-supplied X-Request-ID or generates a UUID; sets response header.
  • backend/src/app.js: res.on('finish') logs { requestId, method, route, statusCode, durationMs } as JSON.
  • backend/src/logger.js: format.errors({ stack: !isProd }) — stack traces only outside production.
  • 5 new tests in tests/request-id.test.js (all passing).

#119 — Multi-dose support per vaccine type

  • contracts/src/storage.rs: VaccinationRecord gains dose_number: Option<u32> and dose_series: Option<u32>. Backward compatible — existing records deserialize with None.
  • contracts/src/mint.rs / lib.rs: mint_vaccination accepts the two new optional params.
  • contracts/src/verify.rs: verify_vaccination returns a 3-tuple (bool, Vec<VaccinationRecord>, Vec<DoseStatus>). DoseStatus contains vaccine_name, doses_received, doses_required, and complete (true when series is finished).
  • Backend: issueSchema accepts optional dose_number/dose_series; passed to contract as Option<u32> ScVals.
  • NFTCard.jsx: renders a pill badge — "2/3 doses" (blue in-progress, green complete) or "Dose 1" when series is unknown. No badge for legacy records.
  • 4 new dose badge tests in NFTCard.test.jsx (all passing).

Testing

  • Python service: 24/24 tests pass (pytest)
  • Backend: no regressions (85 passing, same failures as baseline)
  • Frontend NFTCard: 10/10 tests pass
  • Frontend PatientDashboard: 10/10 tests pass
  • Contract lib: compiles cleanly (cargo build --lib)

Closes dev-fatima-24#115 - Add anomaly detection alerting (Slack/PagerDuty/email)
- python-service/alerting.py: webhook dispatch per flagged issuer
- python-service/scheduler.py: APScheduler job every ANOMALY_SCHEDULE_MINUTES
- main.py: lifespan startup/shutdown for scheduler
- requirements.txt: apscheduler==3.10.4
- tests/test_alerting_scheduler.py: 9 new tests

Closes dev-fatima-24#27 - Paginate GET /vaccination/:wallet
- backend: ?page/?limit params (default 20, max 100), 400 on invalid
- response shape: { data, total, page, limit }
- useVaccination.fetchRecords accepts { page, limit }
- PatientDashboard: server-side pagination replaces client-side usePagination
- Also fixed: missing eventsRoutes import, secrets.js ESM mock,
  invalid wallet address in tests, duplicate keys in frontend package.json

Closes dev-fatima-24#23 - Structured logging with request correlation IDs
- middleware/requestId.js: X-Request-ID header (echo or generate UUID)
- app.js: res.on('finish') logs requestId, method, route, statusCode, durationMs
- logger.js: stack traces omitted in production
- tests/request-id.test.js: 5 new tests

Closes dev-fatima-24#119 - Multi-dose support per vaccine type
- contracts: VaccinationRecord gains dose_number/dose_series (Option<u32>)
- verify.rs: returns DoseStatus per vaccine (doses_received, doses_required, complete)
- backend: issue schema accepts dose_number/dose_series, passes to contract
- NFTCard: dose progress badge (e.g. '2/3 doses', green when complete)
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 29, 2026

@kelly-musk Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@dev-fatima-24 dev-fatima-24 merged commit a61cc11 into dev-fatima-24:main Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants