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/:codeHeader 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 bycfo@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 8Finalization 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 coreoutletsmaster 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): Seedshindi_reviewer,quality_reviewer,restricted_item_owner(OA-06), andfitout_template_owner(OA-07) as configurable role slots insidemaster_data_holdersso 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 0Locked (FV-1..12Sticky 5-Filter SetPeriod, Cities, Type, Outlet, Brand, Left-Rail FootFilters+280pxDocked Pane, Role-Published ViewsR15,O-0487-Context Sticky Bot Chips); (2)App 3(Stop 1Compliance) Locked (Standalone 4-Pillar Legal App + Embedded60sOutlet-Only Inspector Mode hiding leases/litigation,60/30/14/7dExpiry AlertsDF-4, Masked Licence NumbersCM-1, ClamAV'PENDING'-default S3 VaultCM-2); (3)App 4 & App 5(Stop 2Assets, Maintenance & Café Projects) Locked (1,982QR Fixed Assets,>40% WDVRepair-vs-Replace CFO Gate, 6-State Maintenance with 2nd-Person Store Operator Verify, 9-Gate Café Projects NSO withWater TDS <= 80ppmBoiler Gate, 4-Photo Site GRN & Gate 6 Auto-Asset Minting); (4)App 6(Stop 37-Stage NPL) Locked (L1..L7single named owner per gate, CK<=90mBlast Chill & Probe<=+5°CCold-Chain Gate, First-10-Orders Open-Box Rider Gate, 5-Axis Rollout Adoption Roll-Up, Stage 730/60/90dMargin 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 switchoutlet_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, DataasOf, Kiosk Name/State/Last-Seen, Current Shift Lead, Outlet Phone + 1-Tap Call ButtonOS-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 + SectionasOftimestamp (read: false -> 'No data yet', never a false Green0). - 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 perdata_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 ItemsOS-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 — ComplianceCM-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 SummaryAUD-VISIT-5): Last physical manager visit timestamp & days-ago badge (100% Weekly Coveragerule), 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-5onAcctBoard.tsx) & Underlying Data/Compliance Fixes (DF-1..5,CM-1..2): Adds a'Manager view'button on the shared Kiosk board (/kiosk-board) whenoutlet_summary_liveis 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): Configuresoutlets.phone(OS-6), maintainssold_out.watchtracked items, edits/renews outlet licences with masked licence numbers and fulllogChangeaudit (CM-1), and enablesoutlet_summary_live->outlet_summary_ai(OS-7). - Ground Staff (Own Phone or Kiosk without Manager PIN): Never see the Outlet Summary (
403on 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..5Consolidated Outlet Summary & Kiosk Manager View: Single/outlets/:codesummary band (Header Strip + SectionsA..H), Shift Manager included for own outlet (no money figures), Kiosk Manager View with server-side money stripping +60sidle 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-2Outlet Top 20 Read & Tracked Item Enhancements (23A): ExposeoutletTop20(branch)joining weeklytop_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..2Data & Compliance Foundations: Rista 429 retry/backoff (DF-1), daily Stock-Alert Heartbeat (DF-2), Quiet-Hours Hold-Not-Drop (DF-3), scheduled daily60/30/14/7dLicence Expiry Alerts (DF-4), and Licence Edit/Renew +logChangeAudit + Unique(outlet, type, number)+ Masked Licence Numbers (CM-1).
1D. Direct Navigation & Live Pre-Signed-In Routes
- 📋 Jump to Part 2: Full Intake, Domain Design & Industry Benchmarks | 📖 Jump to Part 3: Glossary, DDL & Corpus Appendix
- 🟢 Master 12-Pack & Shared Object Architecture:
/admin/oven-command?doc=MASTER-INTAKE-CATALOG-AND-SHARED-OBJECT-ARCHITECTURE.html - 🟢 Filter View Sticky Spec (FV-1..12):
/admin/oven-command?doc=INTAKE-DESIGN-FILTER-VIEW-STICKY.html - 🟢 Stop 1 Legal & Compliance Spec:
/admin/oven-command?doc=DESIGN-TDD-UIUX-STOP1-LEGAL-COMPLIANCE.html - 🟢 Staging OneOps Manager View:
https://test.oneops.harleys.com/manager
PART 2 · FULL INTAKE & DOMAIN OBJECT DESIGN (1.5 PAGES)
2A. Core User Journeys & Functional Intake Rules
| Journey / Flow | Actor & Trigger | System 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 desktop | GET /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 Items | Manager 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 Fallback | Manager 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-Close | Shift 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 Alerts | Manager checks Section F (Compliance: Check · 1 expiring) -> Config Lead renews licence | Computes 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 Queue | Scheduler 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 & Scope | Key Attributes & Constraints | Cross-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 (outlet | city | brand), scope, rank (1..20) |
SoldOutEpisode & Recon (stockout_events, stockouts, stockout_sync_daily, soldout_reconciliation) | episode_id (PK), branch_code, sku_code, out_at | Append-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_id | opened_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 < 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> <18/20 in stock =Check; <15/20 =Act now. <strong>F (Compliance):</strong> Expired/missing =Act now; ≤30d =Check. <strong>H (Alerts):</strong> <80% acted on =Check. - Kiosk 'Manager View' Security State Machine (
OS-5): <code>KIOSK_BOARD_PUBLIC</code> → Tap <code>[Manager view]</code> → <code>PIN_SHEET_CHALLENGE</code> (Refuses staff or other-outlet mgr) → <code>MANAGER_SUMMARY_READONLY_NO_MONEY</code> → 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) → <code>HOURLY_DATA_VERSION_CACHE</code> → <code>FIGURE_VALIDATOR</code> (Checks every number against B–H) → 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 A507Resolved:</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> Daily60/30/14/7dlicence 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 Reviewer | Standard / Gate Adopted | How 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 Flag | Mounts 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 Alerts | Connects 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 Pillar | Constitutional 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 & Timers | Named 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 correction | Database 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-Routing | CK Crate Short · Cold-Chain Excursion · Packaging Missing · POS SKU Missing · Equipment Down · Staff Shortage | Selecting 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 Proportionality | snooze_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 / Code | Canonical 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 Guard | Per-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 / Artifact | Files / Rows | Target Domain Object | Gate Status |
|---|---|---|---|
pkg2/outlet-summary-page-2026-10-22/01-OWNER-INTENT.md | A513 Single Source of Truth, A308 Stock Alerts Never Pause, A421 Outlet Rollup, A129/A160 Single Store Page, Section 6 Top 20 | Outlet Summary Header + Sections A..H | 100% INCORPORATED |
pkg2/outlet-summary-page-2026-10-22/02-AS-BUILT.md | Rista 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 Map | outletOpenStockouts + outletTop20 + compliance/outlet/:code + storeSalesAsOf | 100% INCORPORATED |
pkg2/outlet-summary-page-2026-10-22/03-PAGE-DESIGN.md & 04-BUILD-LIST.md | OS-1..7 Slices + Kiosk Manager View (60s idle, no money) + AI Summary Fence + DF-1..5 Data Fixes + CM-1..2 Compliance Fixes | GET /api/v2/outlets/:code/summary + kiosk_manager_view_logs + alert_held_queue | 100% 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>

OneOps