# DispatchWithAutomation — Build Spec (Q0 answers + phased plan)

Companion to `MDD_dispatch_automation.md` + ADR-117…123. Authored from DL 2026-07-27.
All §19 decisions RESOLVED (below). Build is VPS-side, dev-first, phase by phase.

## /new-pwa Q0 answers (pre-filled — do NOT re-interview)

| Q | Answer |
|---|---|
| Q0.1 Identity | Module `dispatch` (EVOLVE existing, don't recreate). Short "Dispatch", full "Dispatch — Bulk Courier Automation". Purpose = bulk B2B courier dispatch+tracking+reporting (c+d+other). Palette (a) Orange `#f97316` on Navy. **Theme preset: `navy-classic`** (ADR-100); client report uses per-campaign `theme_preset`. |
| Q0.2 Auth | (a) Hub session gate + **`?next=`** (FIX inherited ADR-001 gap). Roles layered: **Admin** (harish/pramod + list) / **Rep** / **Viewer**. |
| Q0.3 Data | Entities: campaigns, stores(+store_aliases), orders/shipments (extend `consignees`), shipment_events (extend `tracking_events`), shipment_final, call_logs, proof_photos, booking_rules, booking_points. ID format (a) `PREFIX_<ts>_<rand>` for order/campaign refs. Storage: **online-required (PostgREST primary)** for booking/tracking/MIS; **offline draft queue (IndexedDB)** only for the field proof-photo/call-log capture flow (Phase 2). |
| Q0.4 Form | Intake = multi-step (upload → AI field-map review → store-match approval → package/rules → confirm-batch). Auto-save draft YES. Edit submitted: pre-booking YES, post-AWB NO (mirror Shiprocket lock). Save-as-draft YES. |
| Q0.5 Photos | Group "Delivery Proof" (min 1, Phase 2). Camera/gallery choice YES. GPS-stamp optional. Annotation optional. Compression two-mode. |
| Q0.6 GPS | Not a core field-survey GPS app; GPS auto-capture optional, only for proof photos. |
| Q0.6b Maps | YES (store geocoding + zone A–E derivation). **Maps Provider Policy (ADR-004): Google `/mcp-maps` primary, TomTom `/mcp-tomtom` fallback, `/shared/maps-client.js` + server try/catch. Add the failover Playwright test.** |
| Q0.7 Store picker | YES. Source (a) Excel/CSV upload (SheetJS) + server JSON (the consolidation, ADR-121). Full-screen search picker YES. |
| Q0.8 Admin | YES. Admin auto-unlock by empId list; sees all + config (rules, campaign close, retention purge). Viewer = read MIS. |
| Q0.9 Backend | (a) PostgREST `/db/` schema `dispatch`. Google Sheet sync NO. Slides/PPTX: proof deck via **Recce pattern (ADR-095/ADR-024)**. Server HTML report saved to VPS YES (client report). Photos → VPS permanent URLs via **signed proxy (ADR-049)**. External integration via **`shiprocket-proxy` (ADR-117)**. |
| Q0.10 SW | YES. Cache `dispatch-v<N>` (existing is v3 → bump on release). Cache-first, network-fallback. |
| Q0.11 Chrome | Bottom nav (Campaigns / Dispatch / Track / Reports). Hub 🏡 YES. Settings (admin-locked URLs) YES. Toast YES. **FIX inherited ADR-081 safe-bottom gap** (`/shared/safe-bottom.css`). |
| Q0.12 Special | Excel/CSV import YES; admin filter+group-by YES; offline+server report YES; proof image capture YES (Q0.14); repeating per-shipment proof blocks YES; video NO. |
| Q0.13 Amounts | (a) Indian formatting on all money (cost) fields (ADR-071). |
| Q0.14 Proof images | (a) Full editor. Mandatory when a rep marks manual-delivered-with-proof; optional otherwise. CTH (cash hand-to-hand) NO (prepaid B2B). |

## Consistency checklist (Q0 cross-check)
- Online-required vs SW offline: reconciled — booking/tracking/MIS are online (need proxy/DB); SW + IndexedDB draft queue scoped to field proof-capture only. Not a contradiction.
- Auth (hub gate) ↔ Admin mode: consistent (hub identity drives Admin/Rep/Viewer).
- Maps (Q0.6b YES) → failover wiring + Playwright test are mandatory, not optional.
- Proof images (Q0.14) → mandatory-vs-optional modes specified (mandatory on manual-delivered-with-proof).
- Retention purge (ADR-120) is Admin-only + campaign-closed + CSV-export-first — testable as a Playwright assertion.
- Client report PII on unlisted URL (ADR-123) is a deliberate, recorded decision, not an oversight.

## §19 decisions — RESOLVED (2026-07-27)
1. Phasing: **complete build, all phases, in phased order** (nothing deferred as "maybe").
2. Client link: **unlisted URL, no password**, PII included (ADR-123; upgrade path = ADR-048 magic-link).
3. Roles: **Admin + Rep + Viewer**.
4. timex-dashboard: **keep during transition, then retire**.
5. Manual (non-API) booking: **Phase 1**.
6. Store match: **tiered (name+PIN/phone exact auto, fuzzy=suggest) WITH user approval on every link** (ADR-121).
7. Dir anomaly: **fold `/var/www/dispatch/` → `/var/www/360lm/dispatch/`, retire the standalone `dispatch-pwa` container** (TRAEFIK + DOCKER_SHARED locked change window).

## Reusing the proven TIMEX toolchain (the shiprocket-proxy basis)
The battle-tested Python logic lives on **DL** at `C:\Users\Lenovo\Documents\shiprocket-timex\`
(NOT yet on the VPS). Key modules to port into `shiprocket-proxy`: booking (`bulk_book.py`,
`book_remaining_fastest.py`, `reassign_fastest.py`), tracking/status (`check_bluedart_status.py`,
`check_delhivery_status.py`, `check_dtdc_status.py`, `check_xpressbees_status.py`,
`check_other_courier_status.py`), report/ETD logic (`build_client_report.py` incl.
`parse_loose_date` + the DELIVERED/UNDELIVERED fix + `status_bucket`/`reconcile_status`),
master sync (`update_master_sheet.py`), NDR (`ndr/all` usage). **STAGED ON THE VPS at
`/opt/shiprocket-proxy-src/`** (53 `.py` + README, transferred from DL 2026-07-27, root-only 700/600,
NOT web-served). Deliberately excluded (provide separately): Shiprocket creds/.env/auth_state (owner
places creds as a Docker secret) and historical PII campaign data (for the ADR-119 replay harness).

## Phased build plan (dev-first; verify each phase; prod-promote per ADR-060/069 with go-ahead)

### Phase 0 — foundations (governance + infra prep)
- Register on `parallel_sessions.md`; run `vcc_checklist.md` (A–V).
- Fold dir anomaly (ADR §19.7): move `/var/www/dispatch/` → `/var/www/360lm/dispatch/`, retire `dispatch-pwa` container + Traefik router (claim TRAEFIK+DOCKER_SHARED, backup compose, `docker compose config` validate). Get dev-host route.
- Fix inherited gaps: ADR-001 `?next=`, ADR-081 safe-bottom, in `dispatch/index.html`.
- Schema migration `migrate_dispatch_v2.sql` (dev-first on lm360; DB_MIGRATIONS lock): add campaigns, stores, store_aliases, booking_points, booking_rules, proof_photos, call_logs; extend consignees→shipments (+booked_edd, booking_point, package dims); extend tracking_events→shipment_events (+observed_at, edd, source, status_normalized/raw, raw_payload); add shipment_final (REVOKE DELETE + BEFORE-DELETE trigger); shipment_current view; pg_trgm extension; grants (DB_GRANTS lock) + RPCs (ADR-075 errors).

### Phase 1 — MVP (per §19: intake → consolidate → rules/auto-book → tracking backbone → reports → retention)
- `shiprocket-proxy` container (ADR-117): port TIMEX modules; Bearer-JWT fail-closed (ADR-105); booking_point adapters (ADR-122, seed shiprocket-yemo + manual).
- Intake: Excel upload + AI field-map (dispatch-ai), manual entry; store consolidation worklist w/ approval (ADR-121). **2026-07-28**: AI field-map runs on `claude -p` OAuth (ADR-062 tiered chain: claude OAuth → OpenRouter → Anthropic REST → Ollama last resort), NOT Ollama-only — the original Ollama-only path timed out (60s gateway) with no fallback. Output schema for order-booking: name, address_line1, address_line2, city, state, pincode, phones[] (address split per Shiprocket's field-length limits).
- Booking rules engine (ADR-119): zone A–E, priority/blacklist, zone→mode, weight-slab, serviceability gate, tie-break; **replay-test harness vs TIMEX data (mandatory gate before auto-book)**; then rule-driven auto-book.
- Tracking backbone (ADR-118): poll `courier/track/awb` → `shipment_events`.
- Reports: MIS (login, full PII) + Client (unlisted URL, PII) — ADR-123; Excel export.
- Retention/deletion (ADR-120): Admin+closed+CSV-first purge RPC.
- Roles Admin/Rep/Viewer. Manual booking (§19.5). Playwright specs + VCC §V.

### Phase 2 — verification + NDR + proof
- Direct-courier verification tier (ADR-118): BD/Delhivery auto; **DTDC screenshot-relay (persistent Playwright session, TTL+concurrency cap)**; Xpressbees manual worklist.
- NDR: `ndr/all` surface + deep-link to panel + log resolution/call-notes.
- Proof-of-delivery: call_logs + proof_photos (ADR-072/085), photo→PPTX (Recce/ADR-095), signed-proxy serving (ADR-049); offline draft queue (SW).

### Phase 3 — extensibility + intelligence
- Additional booking_points: 360DL Shiprocket account, Blue Dart direct B2B API adapters (ADR-122).
- Carrier scorecard / performance-by-lane allocation (ADR-119 later tier) from accumulated shipment_events.
- cheapest-within-SLA; optional streamed-browser Xpressbees / panel automation if proven.
- Retire timex-dashboard once client report covers it (§19.4).

## Verification & promotion
- Each phase: dev backend web_anon HTTPS roundtrip test + Playwright specs + VCC §V pass + CiC live walkthrough (house norm).
- Prod promotion dev-first per ADR-015/060/069: apply migration to lm360_prod, add `dispatch` to postgrest-prod PGRST_DB_SCHEMAS (finally closes the old prod-broken gap), promote proxy, verify. User go-ahead before each prod step.
- Update `dbt_dispatch.md` after EACH completed step (house cadence).
