Middle Server Recon Inventory
Status
Audited
Date
2026-04-22
Purpose
Capture the legacy middle_server reconciliation behavior that must be preserved or
explicitly redesigned during the recon_service migration.
This document is the source inventory used by:
docs/adr/ADR-002-recon-service-boundary.mddocs/specs/recon/2026-04-22-recon-service-migration.mddocs/plans/recon/2026-04-22-recon-service-implementation.mddocs/runbooks/recon/recon-service-cutover.md
Audited Source Files
servers/middle_server/app/api/routes/pushbullet.pyservers/middle_server/app/api/routes/shooter.pyservers/middle_server/app/api/routes/ws.pyservers/middle_server/app/core/events.pyservers/middle_server/app/core/telegram_bot_mgr.pyservers/middle_server/app/tasks/pushbullet.pyservers/middle_server/app/services/pushbullet/pushbullet_manager.pyservers/middle_server/app/services/openrouter.pyservers/middle_server/app/models/db/models.pyservers/middle_server/app/models/schemas/pushbullet.pyservers/middle_server/app/models/schemas/shooter.pyservers/middle_server/app/resources/errors.pyservers/admin_server/app/api/routes/player/deposit.pyservers/wallet_server/app/api/routes/deposit.pybo/admin/src/ui/views/desktop/ShooterPushBullet/ShooterPushBulletView.vuebo/admin/src/ui/views/desktop/ShooterSms/ShooterSmsView.vuebo/admin/src/ui/views/desktop/ShooterDevices/ShooterDevicesView.vuebo/admin/src/router/asyncRoutes.js
Legacy Route Inventory
Documented route families that are part of the reconciliation domain:
/api/admin/pushbullet/list/api/admin/pushbullet/add_device/api/admin/pushbullet/delete/api/admin/shooter/template/recharge/list/api/admin/shooter/template/recharge/add/api/admin/shooter/template/recharge/delete/api/admin/shooter/phone/list/api/admin/shooter/phone/add/api/admin/shooter/phone/delete/api/admin/shooter/sms/list/api/admin/shooter/sms/get/api/admin/shooter/sms/reset/api/admin/shooter/sms/check
Compatibility-only route family still referenced by bo/admin code:
/api/admin/shooter/device/list/api/admin/shooter/device/trust/api/admin/shooter/device/delete
The device route family is not currently mounted in legacy middle_server, but it is
implemented in the admin frontend and must be treated as part of the migration
compatibility baseline so that v2 can absorb the hidden dependency safely.
Response and Auth Contract
Legacy recon-facing admin routes use the old back-office contract:
- admin requests enter through back-office auth with legacy token and session checks
- successful responses use the legacy envelope
status/msg/data - successful responses refresh the
Authorizationresponse header - successful generic messages use lowercase
success
Legacy shooter-specific business error codes:
41: rule match error42: bank name mismatch43: bank number mismatch44: amount mismatch45: new balance mismatch46: sender mismatch47: SMS not found48: AI regex generation failed49: unsupported SMS50: template already exists
Data Model Inventory
Legacy reconciliation state is persisted in these tables:
shooter_pushbulletshooter_smsshooter_phoneshooter_template_rechargeshooter_device
These names and field semantics must be preserved in phase 1 so that compatibility is proven before any schema cleanup.
shooter_pushbullet
Represents one Pushbullet-linked device/account pair used for SMS ingestion.
Important fields:
- device identity and account metadata
api_access_tokenidenstatusversioncreate_tsupdate_ts
shooter_sms
Represents one captured SMS item across Pushbullet or Telegram ingestion.
Important fields:
- source identity:
p_iden,p_thread_id,sms_channel,sms_id - sender info:
phone,sender - message content:
sms - parsed business fields:
bank_name,bank_num,amount,new_value - matching fields:
order_id,checker - lifecycle fields:
task,task_status,create_ts,update_ts
shooter_phone
Whitelist of phone numbers allowed into automatic SMS handling.
Important fields:
phonestatuscreate_tsupdate_ts
shooter_template_recharge
Recharge SMS template definitions used during parsing.
Important fields:
rulesmsbank_namebank_numamountsendernew_valuestatuscreate_tsupdate_ts
shooter_device
Manual device trust list exposed by bo/admin compatibility UI.
Important fields inferred from UI expectations:
tagphonekeep_online_tsis_trustcreate_ts
SMS Lifecycle Inventory
Legacy task meanings:
0: waiting for SMS ID sync1: waiting for whitelist validation2: waiting for template parse3: waiting for order match or manual review4: handled
Legacy task_status meanings:
0: normal1: unknown Pushbullet device2: phone not in whitelist3: parse failed or no matching template4: matched multiple orders5: no order matched after timeout6: duplicate-name player requires manual review7: no SMS ID matched8: duplicate SMS
Legacy admin filter mapping in /api/admin/shooter/sms/list:
0:task=0,task_status=01:task=1,task_status=02:task=2,task_status=03:task=3,task_status=04:task=4,task_status=011:task=0,task_status=112:task=1,task_status=213:task=2,task_status=314:task=3,task_status=415:task=3,task_status=516:task=3,task_status=6
Worker and Background Flow Inventory
Legacy startup behavior:
- initialize Pushbullet listeners
- initialize Telegram bot manager
- start websocket top-info updater
Legacy scheduled jobs:
- every
10s- SMS ID sync
- whitelist validation
- template parsing
- every
30s- order matching
- missing-SMS backfill
Pushbullet ingestion behavior:
- websocket listener inserts live SMS with
task=0,task_status=0 - missing-SMS backfill inserts pulled SMS with
task=1,task_status=0,sms_channel=2 - SMS ID sync matches by device, thread, sender, body, and timestamp window
Telegram ingestion behavior:
- listens to group, channel broadcast, and system message events
- parses bank SMS-like messages containing
입금or잔액 - supports messages beginning with
보낸사람or[수신날짜] - stores imported rows as
p_iden='tg-sync-bot',sms_id='tg-sync-bot',task=2
Template and Parsing Rules
Recharge template add behavior:
- validates regex compatibility against submitted sample SMS
- if
ruleis empty, calls OpenRouter to generate a regex candidate - generated regex must still be validated against submitted sample SMS
- mismatch responses use the shooter-specific error codes above
Production requirement carried into v2:
- malformed or unsupported samples must fail fast and explicitly
- AI-generated regex is optional enhancement, not required for availability
Matching and Review Behavior
Automatic order matching currently calls:
admin_servercompatibility path/player/deposit/shooter/agree- which forwards to wallet-owned matching behavior
Legacy match response items contain:
transaction_idsms_idis_same
Observed legacy outcomes:
- one clear match can advance to handled state
- duplicate-name player cases use admin list status
16 - no-order timeouts move to
task_status=5
Production hardening rule for v2:
- if multiple candidate orders exist and no single safe match can be chosen, persist
task_status=4instead of reporting the loop as successful - if every per-item publish, parse, or settlement attempt fails within a loop cycle, the loop must report failure to worker health instead of silently remaining green
Top-Info and Admin Integration
Legacy websocket top-info includes:
sms_need_check_cnt
This value is derived from shooter_sms rows where:
task=3task_status=6checker IS NULL
bo/admin uses this value for:
- dashboard badges
- notification sound triggers
- notification popups
- user top-info subscriptions
This counter is therefore part of the external compatibility contract even though it is transported through websocket top-info rather than a shooter REST response.
Migration Decisions Locked By This Inventory
recon_serviceowns the reconciliation domain inservers_v2admin_serviceremains the only back-office edge consumed bybo/adminwallet_serviceremains the only money writer- compatibility covers both the mounted legacy routes and the hidden
/shooter/device/*front-end dependency - phase 1 keeps shooter table names and lifecycle semantics stable