feat: anomaly alerting, pagination, correlation IDs, multi-dose support (#23 #27 #115 #119)#206
Merged
dev-fatima-24 merged 2 commits intoApr 29, 2026
Conversation
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)
|
@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! 🚀 |
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.
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: APSchedulerAsyncIOSchedulerruns the anomaly check on a configurable interval (ANOMALY_SCHEDULE_MINUTES, default 15).python-service/main.py: FastAPIlifespancontext manager starts/stops the scheduler.python-service/requirements.txt: addedapscheduler==3.10.4.high_mint_volume), record count, ISO-8601 timestamp.ALERT_WEBHOOK_URL,ALERT_WEBHOOK_TYPE,PAGERDUTY_ROUTING_KEY,ALERT_EMAIL_TO,ANOMALY_SCHEDULE_MINUTES.tests/test_alerting_scheduler.py(all passing).#27 — Paginate GET /vaccination/:wallet
?page(default 1) and?limit(default 20, max 100); returns400for invalid values.{ data: [], total, page, limit }.useVaccination.fetchRecords(wallet, { page, limit })forwards params to the API.PatientDashboardreplaced client-sideusePaginationwith server-side pagination state; page changes trigger a new fetch.eventsRoutesimport inapp.js,secrets.jsESM mock for Jest, invalid wallet address in integration tests, duplicate keys infrontend/package.json.#23 — Structured logging with request correlation IDs
backend/src/middleware/requestId.js: echoes client-suppliedX-Request-IDor 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.tests/request-id.test.js(all passing).#119 — Multi-dose support per vaccine type
contracts/src/storage.rs:VaccinationRecordgainsdose_number: Option<u32>anddose_series: Option<u32>. Backward compatible — existing records deserialize withNone.contracts/src/mint.rs/lib.rs:mint_vaccinationaccepts the two new optional params.contracts/src/verify.rs:verify_vaccinationreturns a 3-tuple(bool, Vec<VaccinationRecord>, Vec<DoseStatus>).DoseStatuscontainsvaccine_name,doses_received,doses_required, andcomplete(true when series is finished).issueSchemaaccepts optionaldose_number/dose_series; passed to contract asOption<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.NFTCard.test.jsx(all passing).Testing
pytest)cargo build --lib)