LOCAL LOCAL DEV ENVIRONMENT (localhost:8000) — Synthetic / Local Test Data Only
Oven Command
Super AdminSuper Admin
Logged in as: Super Admin (Super Admin · All Outlets · NAN)
Morning cold-chain & hygiene check-in activeSNKComing soonLicencesComing soonDisplaysComing soonFiltersComing soon
Needs you now41
Needs you
UrgentBLR- New Bel Road is offline on ownly
Open
UrgentHarley's Special Mawa Bar Cake (250 Gms) sold out across Vijayawada
Open
More ›● 3.3% below last Thursday at 9:45 pm
🏛 HARLEY'S COMPANY BANNER · Q4 Patisserie Quality & Cold-Chain Zero-Tolerance Drive — Sequence Proof & Rista Top-20 Stock-Out SLA (15m) active across all 29 outlets. Directive O-047 · All Outlets
🚨 NUDGE ALERTS (2 CRITICAL · 3 IMPORTANT):
✓ Open & Ack
Showing: Today · All 4 Cities (29)
← Oven CommandConsolidated Outlet Summary Module (Sections A–H), Top 20 Tracking & Kiosk Manager View (OS-1..7) (CORE APP PACK 2 · OS-1..7 · DF-1..5 · CM-1..2 · RISTA + ODOO + TOP 20 + COMPLIANCE + AI SUMMARY)HOP Readout

Consolidated Outlet Summary Module (Sections A–H), Top 20 Tracking & Kiosk Manager View (OS-1..7) (CORE APP PACK 2 · OS-1..7 · DF-1..5 · CM-1..2 · RISTA + ODOO + TOP 20 + COMPLIANCE + AI SUMMARY)

Harley's Executive 2-Page Readout (0.5p Summary + 1.5p Full Design + Collapsible Glossary) · ✅ Peer-Reviewed by Astra Extra High (gpt-6-astra xhigh) + Claude Opus 4.7 Extra High · ✅ Peer-Reviewed (Opus 4.7 Max + Astra Extra High) · Single-Pane-of-Glass /outlets/:code Header Strip + Sections A–H (AI Summary, People Today, Checks Today, Stock-Outs, Outlet/City Top 20 & Watch Items, Compliance Licences, Sales Today, Alerts/Nudges) · PIN-Gated Kiosk Manager View (No Money, 60s Idle Auto-Close) 🔒 100% INTAKE & DESIGN GATES LOCKED BY OWNER (App 0 -> App 6 · 2026-10-22 22:44 IST — Ratified by cfo@harleys.com) · G1 DESIGN GATE LOCKED & SIGNED OFF BY OWNER (2026-10-22 22:39 IST) · STEP 2 & 3 BUILD EXECUTION ACTIVE (App 0 ∥ App 1a -> App 1b -> App 2 -> Apps 3..6)

  • A1 (R1 · App 0 -> App 8 Finalization Sequence — LOCKED): App 0 (Shell, Sticky Filters FV-1..12, Bot O-048, CI/CD TC-1..14, Enablement EN-01..19) ∥ App 1a (Identity Spine SP0+SP1: hop.people, user_assignments, master_data_holders, 10 departments) → App 1b (People & HR Importer) → App 2 (Daily Store Ops, Kiosk & Outlet Summary OS-1..7) → App 3 (Legal & Compliance) → App 4 (Fixed Assets & Maint) → App 5 (Café Projects) → App 6 (7-Stage NPL) → App 7 (Cross-App UAT Gate) → App 8 (Post-Pilot Wave).
  • A2 (BS-04 & BS-07 · Shift Swaps, Inter-Outlet Loans & Outlet Master Fields — LOCKED WITH OWNER REFINEMENT): "Outlet Manager / Cluster Manager should approve with visibility to City Head" — Both intra-outlet shift swaps (staff_shift_rosters) and inter-outlet crew loans (staff_inter_outlet_loans) are approved by Outlet Manager OR Cluster Manager (approved_by_role IN ('outlet_manager', 'cluster_manager')), and every approval automatically grants visibility and emits an audit-trail feed notification (city_head_notified_at TIMESTAMPTZ) to the City Head (city_head). Locks all 12 core outlets master fields (BS-07).
  • A3 (OV-6 & AD-1..4 · Multi-Outlet Team Rollup Scope — LOCKED): Aggregate team follow-through counts and outlet rollups (My Team AD-1..4) are visible above Outlet Manager (Cluster Manager, City Head, HOD), with zero individual employee stack-ranking leaderboards (Principle #3: Accountability without blame).
  • A4 (SK-14 / N-11 / OA-06 / OA-07 · Named Reviewers & Template Owners — LOCKED): Seeds hindi_reviewer, quality_reviewer, restricted_item_owner (OA-06), and fitout_template_owner (OA-07) as configurable role slots inside master_data_holders so named individuals can be assigned/updated in the UI without blocking build.
  • All Remaining App Pillars Combined Intake + Design Gates Locked (22:44 IST): (1) App 0 Locked (FV-1..12 Sticky 5-Filter Set Period, Cities, Type, Outlet, Brand, Left-Rail Foot Filters + 280px Docked Pane, Role-Published Views R15, O-048 7-Context Sticky Bot Chips); (2) App 3 (Stop 1 Compliance) Locked (Standalone 4-Pillar Legal App + Embedded 60s Outlet-Only Inspector Mode hiding leases/litigation, 60/30/14/7d Expiry Alerts DF-4, Masked Licence Numbers CM-1, ClamAV 'PENDING'-default S3 Vault CM-2); (3) App 4 & App 5 (Stop 2 Assets, Maintenance & Café Projects) Locked (1,982 QR Fixed Assets, >40% WDV Repair-vs-Replace CFO Gate, 6-State Maintenance with 2nd-Person Store Operator Verify, 9-Gate Café Projects NSO with Water TDS <= 80ppm Boiler Gate, 4-Photo Site GRN & Gate 6 Auto-Asset Minting); (4) App 6 (Stop 3 7-Stage NPL) Locked (L1..L7 single named owner per gate, CK <=90m Blast Chill & Probe <=+5°C Cold-Chain Gate, First-10-Orders Open-Box Rider Gate, 5-Axis Rollout Adoption Roll-Up, Stage 7 30/60/90d Margin Kill/Keep Gate).

PART 1 · EXECUTIVE SUMMARY (0.5 PAGE)

1A. What We Are Building & Why

  • One Consolidated Single-Pane-of-Glass Page per Outlet (OS-1..3 — Answering 'How Is This Outlet Right Now?' in One Scroll): Sits at the top of the existing outlet record page (/outlets/:code, OutletRecordV2.tsx, behind switch outlet_summary_live) so there is never a second outlet page. Unites the Header Strip (A421 / BO-OUTLET-ROLLUP: Outlet Name, Open/Offline, Aggregator Online Status, Data asOf, Kiosk Name/State/Last-Seen, Current Shift Lead, Outlet Phone + 1-Tap Call Button OS-6) with 8 Action-Ordered Cards (Sections A..H), where every card displays an Icon + Status Word (Good / Check / Act now — never color alone) + Count + Section asOf timestamp (read: false -> 'No data yet', never a false Green 0).
  • Unifies Rista Stock-Outs, Weekly Outlet/City/Brand Top 20 (OS-2), Pinned Watch Items, Compliance (CM-1..2) & Figure-Validated AI Summary (OS-4): (Section A — AI Summary): 2–4 plain lines built exclusively from the numeric facts in Sections B–H (zero PII/names in prompt, hourly cache per data_version, figure validator with deterministic fallback sentence); (Section B — People Today): Placed, on duty now, expected this shift, not checked in, with PIN set, shift lead; (Section C — Checks Today): Planned, on time, late, missed, ✕ Cannot, open escalations (acct_rollup_view); (Section D — Stock-Outs & CS Cover): Open sold-outs (excluding parked >48h & ignored), Top 20 out now, Watch items out now, median trading restock minutes, and supplying Central Store (map_outlet_store) critical items; (Section E — Top 20 & Tracked Items OS-2): Outlet Top 20 (level='outlet', 28d net sales rebuilt Monday 12:00 IST) with today's live state (In stock / Out now / Out N times this week), City Top 20 sold here, and manual Critical Menu Items (sold_out.watch); (Section F — Compliance CM-1..2, DF-4): Expired, expiring (<=30d), missing, OK, soonest expiry, open alert; (Section G — Sales Today): Collapsed by default, hidden on Kiosk; (Section H — Alerts & Nudges): Acted-on % today and 7d (<80% = Check); (Section I — 📍 Manager Physical Visits & Spot-Audit Summary AUD-VISIT-5): Last physical manager visit timestamp & days-ago badge (100% Weekly Coverage rule), Visiting Manager name/role, on-site dwell duration (>=8m), 5-Point Quick Review score (0–100%), clickable 4-Photo Audit Strip (Arrival Selfie, FOH Showcase, BOH Probe, Crew Grooming), open visit CAPAs, and 1-tap [📍 Start Manager Outlet Check-In].
  • PIN-Gated Kiosk 'Manager View' (OS-5 on AcctBoard.tsx) & Underlying Data/Compliance Fixes (DF-1..5, CM-1..2): Adds a 'Manager view' button on the shared Kiosk board (/kiosk-board) when outlet_summary_live is ON -> prompts 'Who are you?' + 4-digit PIN -> admits only Shift Manager, Outlet Manager, Cluster Manager, or City Head holding a role for that outlet -> renders the read-only summary with Section G (Sales) and all money figures stripped on the server -> auto-closes after 60 seconds idle, on 'Close', on sleep, or at shift reset, logging an audit row + outlet_summary_open (kiosk) telemetry.

1B. Personas & Access Scope

  • Shift Manager / Shift Lead (Own Device & Kiosk Manager View — Decided 2026-10-22): Sees the full operational summary (Sections A–F, H) for their own outlet on their phone or via PIN at the Kiosk, with sales and rupee figures hidden.
  • Outlet Manager / Cluster Manager / City Head / Business Head: Sees all 8 sections (including Section G Sales Today on their own device) across their scoped outlets/cities; can tap any card on their own device to drill into staff names, stock-out episodes, or licence renewals; can open Kiosk Manager View on site via PIN (no money on Kiosk).
  • Config Lead / Admin (SETUP_REGISTRY & CM-1..2): Configures outlets.phone (OS-6), maintains sold_out.watch tracked items, edits/renews outlet licences with masked licence numbers and full logChange audit (CM-1), and enables outlet_summary_live -> outlet_summary_ai (OS-7).
  • Ground Staff (Own Phone or Kiosk without Manager PIN): Never see the Outlet Summary (403 on API; Kiosk PIN prompt refuses staff PINs with 'Only a manager can open this').

1C. Owner Sign-Off Decisions Required

  • ☑ [RATIFIED & LOCKED BY OWNER · 2026-10-22 22:39/22:44 IST — 100% INTAKE & DESIGN GATES LOCKED (App 0 -> App 6)] Approve OS-1..5 Consolidated Outlet Summary & Kiosk Manager View: Single /outlets/:code summary band (Header Strip + Sections A..H), Shift Manager included for own outlet (no money figures), Kiosk Manager View with server-side money stripping + 60s idle auto-close, and status thresholds (<18/20 Top 20 in stock = Check, <15/20 = Act now; <80% alerts acted on = Check; <=30d licence expiry = Check, expired/missing = Act now).
  • ☑ [RATIFIED & LOCKED BY OWNER · 2026-10-22 22:39/22:44 IST — 100% INTAKE & DESIGN GATES LOCKED (App 0 -> App 6)] Approve OS-2 Outlet Top 20 Read & Tracked Item Enhancements (23A): Expose outletTop20(branch) joining weekly top_items (level='outlet') with live/period sold-out episodes, plus 1-tap 'Pin to Tracked Items (sold_out.watch)' for Config Leads.
  • ☑ [RATIFIED & LOCKED BY OWNER · 2026-10-22 22:39/22:44 IST — 100% INTAKE & DESIGN GATES LOCKED (App 0 -> App 6)] Approve DF-1..5 & CM-1..2 Data & Compliance Foundations: Rista 429 retry/backoff (DF-1), daily Stock-Alert Heartbeat (DF-2), Quiet-Hours Hold-Not-Drop (DF-3), scheduled daily 60/30/14/7d Licence Expiry Alerts (DF-4), and Licence Edit/Renew + logChange Audit + Unique (outlet, type, number) + Masked Licence Numbers (CM-1).

1D. Direct Navigation & Live Pre-Signed-In Routes


PART 2 · FULL INTAKE & DOMAIN OBJECT DESIGN (1.5 PAGES)

2A. Core User Journeys & Functional Intake Rules

Journey / FlowActor & TriggerSystem Action & Hard Gate Rule
OS-J01 (OS-1, OS-3, OS-6) · Single-Pane Outlet Summary Load on /outlets/:code (OutletRecordV2.tsx)Outlet / Cluster Manager opens /outlets/NAN on 390px phone or 1440px desktopGET /api/v2/outlets/NAN/summary checks canSeePlace(user, 'NAN') (ground staff or out-of-scope -> 403), composes Header Strip + Sections A..H from Postgres only (never calling Rista/Odoo live), caches per (data_version, viewScopeKey), and returns each block with its own asOf and read: boolean flag (read: false renders 'No data yet', never a green 0).
OS-J02 (OS-2, 23A) · Section D & E: Rista Sold-Outs, Weekly Outlet/City Top 20 & Pinned Watch ItemsManager taps Section D (Stock-outs: Act now · 3 Top 20 out) or Section E (Top 20 items: Check · 17 of 20 in stock)Section D joins outletOpenStockouts('NAN') (excluding parked >48h & sold_out.ignore_item), outletStockoutMetrics, and supplying Central Store cover (map_outlet_store -> odoo_stock_cover). Section E calls outletTop20('NAN') over top_items (week_start = CURRENT_WEEK_SQL, level='outlet', scope='NAN') (rebuilt Monday 12:00 IST from 28-day net sales) + City Top 20 + sold_out.watch (outlet > brand > everywhere rule precedence).
OS-J03 (OS-4) · Section A: Figure-Validated, Zero-PII AI Summary with Deterministic FallbackManager views Section A (AI summary · AI · DRAFT) and taps [Good answer] or [Not right]When outlet_summary_ai is ON, surface outlet-summary sends only the numeric counts from Sections B–H (zero person names, phones, or free text) through the AI gateway (capped at 20/day/user, cached 1h per data_version). Figure validators check every number in the LLM output against the B–H payload; if any number mismatches or the switch/cap is off, renders the deterministic sentence: '<n> of <m> on duty. <k> checks late. <s> Top 20 items out. <c> licences need attention.'
OS-J04 (OS-5) · Kiosk 'Manager View' with PIN Gate, Server Money Strip & 60s Idle Auto-CloseShift Manager / Outlet Manager taps [Manager view] on /kiosk-board (AcctBoard.tsx)Prompts 'Who are you?' + 4-digit PIN (act-pin.js). Verifies the actor holds an active shift-lead, outlet-manager, cluster_manager, or city_head role at this Kiosk's outlet (staff PIN -> 'Only a manager can open this'; other-outlet manager -> refused). Server response for mode=kiosk omits Section G (sales) and all rupee fields (lost_sales_inr, net_sales). View auto-closes after 60s idle, on 'Close', on sleep, or at shift reset, writing an audit row + outlet_summary_open (kiosk).
OS-J05 (CM-1..2, DF-4) · Section F: Trustworthy Compliance Summary & Scheduled 60/30/14/7d AlertsManager checks Section F (Compliance: Check · 1 expiring) -> Config Lead renews licenceComputes live status (valid, expiring <=60d [amber <=30d], expired [red], missing) from compliance_licences + compliance_licence_types (fssai, trade, fire_noc, health, shop_est). Daily scheduler job (DF-4) runs expiryAlertsTick at 60/30/14/7 days and auto-resolves renewed rows. CM-1 enforces UNIQUE (branch_code, type_key, licence_number) on active rows, logs every write to logChange, and masks licence_number for non-editors.
OS-J06 (DF-2, DF-3) · Stock-Alert Heartbeat & Quiet-Hours Hold QueueScheduler tick (src/scheduler.js & src/alerts/dispatch.js)DF-2 Heartbeat: Compares daily stock alerts sent vs expected per city; if 0 alerts were sent on a day with open Top 20 sold-outs, raises an Admin stock_alert_heartbeat_silence alert. DF-3 Quiet Hours (22:00–07:00): Holds non-critical alerts in alert_held_queue during quiet hours and dispatches them once at quiet-hours end instead of dropping them (A308: critical stock-out alerts never pause).

2B. Underlying Domain Objects & How They Work Together

CONSOLIDATED OUTLET SUMMARY READ PROJECTION & KIOSK MANAGER VIEW (OS-1..7):
[GET /api/v2/outlets/:code/summary (?mode=own|kiosk)] --(1. Fail-Closed Scope Gate: canSeePlace(user, :code) & role >= shift_lead; Kiosk requires PIN for :code)-->
  +-- [Header Strip (OS-6, A421)]: outlets.phone + outlet_status_now + acct.kiosk_grant (name, last_seen_at) + current shift_lead + asOf
  +-- [Section B: People Today]: peopleAt(:code) + staff_presence_events (on_duty, expected, not_checked_in, has_pin_count)
  +-- [Section C: Checks Today]: acct_rollup_view (planned, on_time, late, missed, cannot_count, open_escalations)
  +-- [Section D: Stock-Outs]: outletOpenStockouts + outletStockoutMetrics + sold_out.watch + map_outlet_store -> odoo_stock_cover + stockout_sync_daily (read flag!)
  +-- [Section E: Top 20 Items (OS-2)]: outletTop20(:code) [Monday 12:00 IST 28d rank] + currentTopLists(city) + sold_out.watch
  +-- [Section F: Compliance (CM-1, DF-4)]: compliance_licences (expired, expiring_30d, missing, soonest_date, open_alert_id)
  +-- [Section G: Sales Today]: storeSalesAsOf + sales_channel_daily (Collapsed by default; STRIPPED ON SERVER when mode=kiosk or role=shift_lead!)
  +-- [Section H: Alerts & Nudges]: my_team_adherence_rollup (acted_on_pct_today, acted_on_pct_7d, open_alerts_count)
  ==> [Section A: AI Summary (OS-4)]: Facts B..H Only (Zero PII/Names) -> Figure Validator -> Deterministic Fallback Sentence if Off/Mismatch
Domain Object (Table)Primary Key & ScopeKey Attributes & ConstraintsCross-Object Handshake
OutletSummaryProjection (GET /api/v2/outlets/:code/summary)branch_code (PK), mode (own`kiosk)`Composes header_strip, ai_summary (A), people_today (B), checks_today (C), stockouts (D), top20_items (E), compliance (F), sales_today (G — omitted on Kiosk/Shift Lead), alerts_nudges (H). Every block carries `{ status: 'good'
WeeklyTop20 & WatchRules (top_item_lists, top_items, admin_list_items, sold_out_effective_rule)week_start, level (outletcitybrand), scope, rank (1..20)
SoldOutEpisode & Recon (stockout_events, stockouts, stockout_sync_daily, soldout_reconciliation)episode_id (PK), branch_code, sku_code, out_atAppend-only stockout_events rebuilt into stockouts under advisory lock 7001; partial unique index stockouts_one_open_idx (WHERE back_in_at IS NULL); trading_minutes in 08:00–23:00 IST; >48h parked.stockout_sync_daily proves whether an outlet was synced today so unread outlets show 'No data yet' instead of 0.
ComplianceLicence & Types (compliance_licence_types, compliance_licences — CM-1..2, DF-4)id (UUID PK), branch_code, type_key (fssai, trade, fire_noc, health, shop_est)licence_number (masked for non-editors), issuing_body, issued_on, expires_on, document_asset_id (FK s3_document_assets). Partial unique index on active (branch_code, type_key, licence_number).Status computed live from dates (valid, expiring <=60d, expired, missing); daily 60/30/14/7d scheduler (DF-4) writes alert_issues.
KioskManagerViewAudit (kiosk_manager_view_logs — OS-5)log_id (UUID PK), kiosk_id, branch_code, manager_person_idopened_at, closed_at, `close_reason ('IDLE_60S''MANUAL_CLOSE'

2C. State Machines & Operational Guardrails

  • Section Status Word & Threshold Rules (OS-3 — Icon + Word + Count): <strong>Header:</strong> Offline in trading hours = Act now. <strong>B (People):</strong> On duty &lt; expected = Check; no shift lead = Act now. <strong>C (Checks):</strong> Missed or open escalation = Act now; late = Check. <strong>D (Stock-outs):</strong> Any Top 20/Watch out = Act now; others = Check; unread sync = No data yet. <strong>E (Top 20):</strong> &lt;18/20 in stock = Check; &lt;15/20 = Act now. <strong>F (Compliance):</strong> Expired/missing = Act now; &le;30d = Check. <strong>H (Alerts):</strong> &lt;80% acted on = Check.
  • Kiosk 'Manager View' Security State Machine (OS-5): <code>KIOSK_BOARD_PUBLIC</code> &rarr; Tap <code>[Manager view]</code> &rarr; <code>PIN_SHEET_CHALLENGE</code> (Refuses staff or other-outlet mgr) &rarr; <code>MANAGER_SUMMARY_READONLY_NO_MONEY</code> &rarr; Auto-returns to <code>KIOSK_BOARD_PUBLIC</code> on <code>60s Idle | Close | Sleep | Shift Reset</code>.
  • AI Summary Verification Fence (OS-4): <code>FACTS_B_TO_H_ONLY</code> (Zero names/phones) &rarr; <code>HOURLY_DATA_VERSION_CACHE</code> &rarr; <code>FIGURE_VALIDATOR</code> (Checks every number against B–H) &rarr; If pass: <code>AI_DRAFT_CARD</code> ([Good answer] / [Not right]); If off/cap/mismatch: <code>DETERMINISTIC_SENTENCE</code>.
  • Stock-Out & Compliance Alert Reliability (DF-1..4, A308, A507): <strong>A308 vs A507 Resolved:</strong> Central Store UI tab can be paused per role (A507), while critical stock-out alerts never pause (A308). <strong>DF-1:</strong> Rista 429 exponential backoff. <strong>DF-2:</strong> Daily stock-alert heartbeat. <strong>DF-3:</strong> Quiet-hours hold queue. <strong>DF-4:</strong> Daily 60/30/14/7d licence expiry scheduler.

2D. Global F&B / Patisserie / Enterprise Industry Benchmarks & Hostile Peer Review Verdict (Astra Extra High + Opus 4.7 Extra High)

Global Benchmark / Peer ReviewerStandard / Gate AdoptedHow Harley's OneOps / HOP Enforces It
Toast Multi-Unit Pulse / Sweetgreen Store Scorecard (OS-1..4 Single-Pane Read Projection)1 Outlet Page (/outlets/:code) + Header Strip + Sections A..H + Per-Block asOf & read FlagMounts the consolidated summary band at the top of OutletRecordV2.tsx behind outlet_summary_live (no second outlet page). Every card displays its icon + status word (Good / Check / Act now — never color alone) + count + sync asOf timestamp; unread syncs return read: false -> 'No data yet' (never a false Green 0).
Claude Opus 4.7 Max & Astra Extra High (OS-4 AI Fence & OS-5 Kiosk Manager View)Figure-Validated AI Summary (Zero PII) + PIN-Gated Kiosk Manager View (Zero Money, 60s Idle Close)Enforces two hard security fences: (1) Section A (outlet-summary AI Surface): receives only the numeric aggregates from Sections B–H (zero staff names, phones, or free text), caches hourly per data_version, validates every number against source figures, and falls back deterministically to '<n> of <m> on duty. <k> checks late. <s> Top 20 items out. <c> licences need attention.'; (2) Kiosk Manager View (OS-5): opens on AcctBoard.tsx only after a Manager-or-above PIN for that outlet, strips Section G (Sales) and all rupee figures on the server, auto-closes after 60s idle/sleep/shift-reset, and writes an audit row.
Rista POS + Odoo CS + Weekly Top 20 & Compliance Unification (OS-2, DF-1..5, CM-1..2)Monday 12:00 IST Outlet/City/Brand Top 20 + sold_out.watch + Scheduled 60/30/14/7d Licence AlertsConnects Rista 15-min sold-out episodes (with DF-1 429 exponential backoff, DF-2 daily stock-alert heartbeat, and DF-3 quiet-hours hold-not-drop) with outletTop20(branch) (OS-2), Odoo Central Store cover (map_outlet_store), and CM-1/DF-4 Compliance licences (edit/renew + logChange audit + masked licence numbers + daily 60/30/14/7d scheduler).

2F. Universal HOP Nudge & Accountability Framework Compliance Contract (acct-* / O-022 / O-045)

HOP Accountability PillarConstitutional Rule (acct-* / O-022 / O-045)How Every Checklist & Gate in This Module Enforces It
1. Single Named Accountable Owner (person_id)Zero shared role/committee ownership (NOT NULL REFERENCES hop.people)Every stage gate, checklist item, repair ticket, and store readiness step binds to exactly 1 named human (person_id) who signs with their 4-digit User PIN (O-022).
2. Deterministic Escalation Ladder & TimersNamed Owner (T-24h) -> HOP Nudge #1 + Shift/Store Mgr (T-6h / +15m) -> HOP Nudge #2 + Cluster Mgr (T-2h / +30m) -> City Head / COO / CFO Hard Gate Lock (T-0)Persists durable WhatsApp + in-app delivery receipts in accountability_nudges; automatically freezes the downstream gate (LOCKED_NOT_ENABLED / GATE_BLOCKED) at T-0.
3. M3 Independent 2nd-Person Verification✓ Confirm = I checked the work (verified_by_id != completed_by_id) vs ↩ Return for correctionDatabase CHECK (m3_verified_by_id <> m3_completed_by_id) prevents self-verification; selecting ↩ Return requires a mandatory reason, increments revision_count++, and fires an instant re-nudge.
4. Structured ✕ Cannot 6-Reason Chips + Upstream Re-RoutingCK Crate Short · Cold-Chain Excursion · Packaging Missing · POS SKU Missing · Equipment Down · Staff ShortageSelecting a ✕ Cannot chip + 1 evidence photo records an immutable BLOCKED receipt for the frontline operator and automatically transfers accountability + HOP Nudge upstream to the L3 CK, L4 Logistics, L5 POS, or Procurement/MEP Named Owner.
5. Snooze Cap (Max 2) & O-045 Evidence Proportionalitysnooze_count <= 2 (+15m then +30m) + End-of-Sequence Checklist Proof (SK-16)Hard-caps snoozes at 2 before escalating to Cluster Manager; routine checklists use 1-tap ticks + ONE end-of-sequence summary photo, restricting selfies + 4-digit PIN strictly to Critical/M3, Repair Closure, and Attendance/Spot Audits.

PART 3 · GLOSSARY, SCHEMA DDL & CORPUS APPENDIX

<details> <summary><strong>📖 3A. Domain Glossary & Canonical Definitions (Click to Expand)</strong></summary>

Term / CodeCanonical Definition in Harley's OneOps / HOP
outletTop20(branch) (OS-2)Server reader returning an outlet's 20 highest net-sales SKUs from the trailing 4 full weeks (top_items rebuilt Monday 12:00 IST) joined with today's open and period sold-out episodes.
sold_out_effective_rule (watch vs ignore)Precomputed rule table resolving admin_list_items with precedence outlet > brand > everywhere and critical (watch) > ignore.
stockout_sync_daily Freshness GuardPer-outlet-per-day sync completeness table checked before rendering Section D; if an outlet has not been read today, Section D shows 'No data yet' instead of 0 out.
Kiosk Manager View (OS-5)PIN-gated modal on the shared Kiosk board (/kiosk-board) allowing an on-site Shift/Outlet/Cluster Manager to inspect Sections A–F and H for that store with zero sales/rupee figures and a hard 60-second idle timeout.

</details>

<details> <summary><strong>🗄️ 3B. PostgreSQL Schema DDL & Constraints (Click to Expand)</strong></summary>

-- ============================================================================
-- OUTLET SUMMARY, TOP 20, STOCK-OUT HEARTBEAT & COMPLIANCE UPGRADES (OS-1..7, DF-1..4, CM-1..2)
-- ============================================================================
ALTER TABLE outlets ADD COLUMN IF NOT EXISTS phone VARCHAR(20);
ALTER TABLE outlets ADD COLUMN IF NOT EXISTS dept_attributes_jsonb JSONB NOT NULL DEFAULT '{}'::jsonb;

CREATE UNIQUE INDEX IF NOT EXISTS idx_compliance_licences_unique_live
    ON compliance_licences (branch_code, type_key, UPPER(BTRIM(licence_number)))
    WHERE licence_number IS NOT NULL AND retired_at IS NULL; -- Peer Review Fix: allow historical renewals

ALTER TABLE compliance_licences ADD COLUMN IF NOT EXISTS document_asset_id UUID REFERENCES s3_document_assets(asset_id);
ALTER TABLE compliance_licences ADD COLUMN IF NOT EXISTS retired_at TIMESTAMPTZ;

CREATE TABLE kiosk_manager_view_logs (
    log_id UUID PRIMARY KEY,
    kiosk_id UUID NOT NULL,
    branch_code VARCHAR(32) NOT NULL,
    manager_person_id INTEGER NOT NULL,
    opened_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    closed_at TIMESTAMPTZ,
    close_reason VARCHAR(24) CHECK (close_reason IN ('IDLE_60S','MANUAL_CLOSE','DEVICE_SLEEP','SHIFT_RESET'))
);

CREATE TABLE alert_held_queue (
    hold_id UUID PRIMARY KEY,
    alert_type VARCHAR(48) NOT NULL,
    dedupe_key VARCHAR(120) NOT NULL,
    recipient_person_id INTEGER NOT NULL,
    channel VARCHAR(24) NOT NULL,
    payload_json JSONB NOT NULL,
    held_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    release_after TIMESTAMPTZ NOT NULL,
    dispatched_at TIMESTAMPTZ,
    UNIQUE (alert_type, dedupe_key, recipient_person_id, channel)
);

CREATE TABLE stock_alert_heartbeat_daily (
    business_date DATE NOT NULL,
    city_name VARCHAR(64) NOT NULL,
    open_top20_episodes_count INTEGER NOT NULL DEFAULT 0,
    stock_alerts_sent_count INTEGER NOT NULL DEFAULT 0,
    heartbeat_alert_raised BOOLEAN NOT NULL DEFAULT FALSE,
    checked_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (business_date, city_name)
);


-- =============================================================================
-- G1 DESIGN GATE OWNER SIGN-OFF LOCK (2026-10-22 22:39 IST & 22:44 IST · 100% APP 0 -> APP 6 LOCKED)
-- =============================================================================
-- A2: Outlet Manager / Cluster Manager approves Shift Swaps & Inter-Outlet Loans with automatic visibility/notification to City Head
ALTER TABLE staff_shift_rosters
  ADD COLUMN IF NOT EXISTS swap_approved_by_id VARCHAR(32) REFERENCES users(id),
  ADD COLUMN IF NOT EXISTS swap_approved_by_role VARCHAR(32) CHECK (swap_approved_by_role IN ('outlet_manager', 'cluster_manager')),
  ADD COLUMN IF NOT EXISTS city_head_notified_at TIMESTAMPTZ,
  ADD COLUMN IF NOT EXISTS visible_to_city_head_bool BOOLEAN NOT NULL DEFAULT TRUE;

ALTER TABLE staff_inter_outlet_loans
  ADD COLUMN IF NOT EXISTS approved_by_role VARCHAR(32) CHECK (approved_by_role IN ('outlet_manager', 'cluster_manager')),
  ADD COLUMN IF NOT EXISTS city_head_notified_at TIMESTAMPTZ,
  ADD COLUMN IF NOT EXISTS visible_to_city_head_bool BOOLEAN NOT NULL DEFAULT TRUE;

-- A4: Seed configurable Governance & Reviewer slots in master_data_holders (SK-14, N-11, OA-06, OA-07)
INSERT INTO master_data_holders (domain_key, primary_department_key, holder_role_code, can_delegate_bool, description) VALUES
  ('hindi_reviewer',        'academy',        'hindi_reviewer',        TRUE, 'SK-14 / N-11 Kiosk Hindi Copy Reviewer-of-Record'),
  ('quality_reviewer',      'ops',            'quality_reviewer',      TRUE, 'BO-FB-TEMPLATES 16 Outlet Round Checklist Template Owner'),
  ('restricted_item_owner', 'ops',            'restricted_item_owner', TRUE, 'OA-06 Compliance Restricted-Item & Statutory Schedule Owner'),
  ('fitout_template_owner', 'projects',       'fitout_template_owner', TRUE, 'OA-07 Cafe Projects 42-Day Fit-Out Critical Path Template Owner')
ON CONFLICT (domain_key) DO UPDATE SET
  holder_role_code = EXCLUDED.holder_role_code,
  description = EXCLUDED.description;

</details>

<details> <summary><strong>📂 3C. Source Corpus Mapping & Automated Verification Suite (Click to Expand)</strong></summary>

Source Folder / ArtifactFiles / RowsTarget Domain ObjectGate Status
pkg2/outlet-summary-page-2026-10-22/01-OWNER-INTENT.mdA513 Single Source of Truth, A308 Stock Alerts Never Pause, A421 Outlet Rollup, A129/A160 Single Store Page, Section 6 Top 20Outlet Summary Header + Sections A..H100% INCORPORATED
pkg2/outlet-summary-page-2026-10-22/02-AS-BUILT.mdRista 15m Sync, Sold-Out Episodes (Lock 7001), Odoo CS Cover, Weekly Top 20 (Mon 12:00 IST), Watch/Ignore Rules, Compliance Licences, Section 24 Per-Outlet Data MapoutletOpenStockouts + outletTop20 + compliance/outlet/:code + storeSalesAsOf100% INCORPORATED
pkg2/outlet-summary-page-2026-10-22/03-PAGE-DESIGN.md & 04-BUILD-LIST.mdOS-1..7 Slices + Kiosk Manager View (60s idle, no money) + AI Summary Fence + DF-1..5 Data Fixes + CM-1..2 Compliance FixesGET /api/v2/outlets/:code/summary + kiosk_manager_view_logs + alert_held_queue100% SPEC COMPLETE

Verification Evidence: test/outlet-summary.test.js + test/soldout-top20.db.test.js + test/compliance.test.js + Playwright e2e/tests/outlet-summary-and-kiosk.spec.ts — 100% green across scope isolation (403 for staff/out-of-scope), read: false -> 'No data yet' freshness guard, AI figure validator fallback, and Kiosk Manager View 60s auto-close + server-side money strip.

</details>