ADR-002: Recon Service Boundary
Status
Accepted
Date
2026-04-22
Context
middle_server contains a heavy SMS reconciliation capability set:
- Pushbullet device management
- SMS whitelist management
- recharge template management
- AI-assisted regex generation
- SMS ingestion and task-state progression
- missing-message backfill
- Telegram SMS ingestion
- manual review APIs
- automatic order matching
- back-office top-info counters
In servers_v2, we need to migrate this capability without:
- turning
admin_serviceinto a new leftover monolith - letting the admin frontend call multiple backend services directly
- violating the single money writer rule
Decision
We will introduce a dedicated recon_service plus recon_worker.
Ownership:
admin_serviceremains the only back-office HTTP entrypoint forbo/admin.recon_serviceowns SMS reconciliation domain data and APIs.recon_workerowns long-running listeners, polling loops, parsing, matching, and admin-refresh signaling.wallet_serviceremains the only money writer.
Call flow:
bo/admin->admin_service->recon_servicerecon_servicedoes not directly mutate money state- final approval still flows through
admin_serviceandwallet_service
Compatibility rules:
- existing back-office routes such as
/api/admin/pushbullet/*and/api/admin/shooter/*remain externally stable - admin legacy token and session semantics stay at the
admin_serviceedge - top-info counters such as
sms_need_check_cntcontinue to be aggregated byadmin_service
Consequences
Positive:
- clear domain ownership
- clean separation between reconciliation and money mutation
- front-end remains largely unchanged
- worker lifecycle and health can be independently managed
Negative:
- requires one more internal service and worker runtime
- requires admin compatibility adapter routes and a new internal client
Constraints
recon_workerhealth must be based on freshness of successful loop progress, not just process liveness- no production cutover is complete while
/shooter/device/*and other related legacy routes remain unclassified