Skip to main content

J-12 — End-of-Day Cash Drawer Close

One-liner: Receptionist closes the till; system reconciles cash, surfaces variance, and finalises the day.

1. Purpose

End-of-shift / end-of-day, the receptionist closes the till. The Electron app reconciles total cash received vs. expected, presents a variance report, prompts for explanations, and produces a sealed EOD record (cash-in-drawer, total receipts by method, taxes, key-issuance count, dispute count). Outcome: a sealed EOD report tied to the receptionist's session, with variance documented, ready for finance review.

2. Persona Context

  • Persona: Receptionist (closing); Finance (reviewer).
  • Surface: Electron Desktop.
  • Primary BFF: bff-backoffice-service.
  • Backing services: payments-service, folio-service, audit-service, reporting-service.
  • Preconditions: Drawer was opened with start float at start-of-shift; receptionist signed in; tenant timezone configured.
  • Trigger: Receptionist clicks "Close drawer" or "End of day" at shift change / end of business day.

3. Entry Points

#EntryNotes
1"Close drawer" CTADefault
2Auto-prompt at tenant-configured EOD timeP2

4. Screen-by-Screen Flow

4.1 EndOfDaySummaryScreen

  • Layout: Date + shift, expected cash (start float + cash receipts - cash refunds - drops), expected card totals, taxes by category, key-issuance count, dispute count, totals reconciled vs ledger.
  • Components: EodSummaryTable, Pill (status), Button ("Begin close").
  • Offline: Reads from SQLite; can finalise locally and queue.
  • AI: None in P1; P2 — anomaly highlight (unusual variance).
  • Errors: Open folios still pending -> warning with link to resolve.
  • Loading: Mount <= 200 ms.
  • A11y: Table semantics; status announced.
  • RTL: Mirror.
  • Perf: <= 200 ms.
  • Telemetry: frontend.eod.summary_viewed.

4.2 CashCountForm

  • Layout: Denominations table (notes + coins) with quantity inputs; computed total; variance (vs expected) shown live; signature pad / manager PIN.
  • Components: DenominationCountTable, VarianceDisplay, SignaturePad, ManagerPinPad.
  • Offline: Local persist.
  • AI: None.
  • Errors: Negative quantity disallowed; variance > threshold requires manager approval.
  • Loading: Sub-200 ms.
  • A11y: Each denomination input is labelled; variance announced live.
  • RTL: Mirror; numerals localised.
  • Perf: Recompute <= 100 ms.
  • Telemetry: frontend.eod.cash_counted { variance }.

4.3 VarianceExplanationForm

  • Layout: Free-text explanation, photo evidence (optional), responsibility flag (mistake / theft suspected / other), manager sign-off.
  • Components: Form, PhotoUpload, ManagerPinPad.
  • Offline: Editable; queued.
  • AI: None.
  • Errors: Required when variance != 0.
  • Loading: Sub-200 ms.
  • A11y: Field labels; manager sign-off announced.
  • RTL: Mirror.
  • Perf: Submit <= 500 ms.
  • Telemetry: frontend.eod.variance_explained { reason }.

4.4 EodReportPrintAndSeal

  • Layout: Final EOD report preview; "Print" + "Email to manager" + "Seal day" actions; sealed pill on success.
  • Components: ReportPreview, Button (variants).
  • Offline: Print local; email queued; seal recorded local with cryptographic hash.
  • AI: None.
  • Errors: Print failure -> retry; seal already done -> banner.
  • Loading: Print <= 5 s.
  • A11y: Sealed pill announced; report content navigable.
  • RTL: Mirror.
  • Perf: Total flow <= 5 min wall-clock.
  • Telemetry: frontend.eod.sealed { dayId }.

5. State Machine

6. Data Requirements

6.1 Server state

  • GET /api/v1/eod/summary?day=...&sessionId=...
  • POST /api/v1/eod/cash-count (idempotent)
  • POST /api/v1/eod/variance (idempotent)
  • POST /api/v1/eod/seal (idempotent; returns sealed report id + hash)

6.2 Local persistence

  • SQLite eod_sessions_local, eod_cash_counts_local, eod_variances_local, outbox, audit_local.
  • Sealed report stored locally with cryptographic hash.

6.3 Idempotency

  • All mutations carry X-Idempotency-Key.

7. AI Behavior

n/a in P1; P2 — variance anomaly highlight.

8. Offline Behavior

  • Reads from SQLite snapshot.
  • Cash count, variance, manager approval all local.
  • Report seal local; cryptographic hash; reconciled on reconnect.

9. Error States

ErrorTriggerUX shownRecoveryTelemetry
OPEN_FOLIOS_AT_EODFolios still pendingWarning with link to resolveUser resolvesfrontend.eod.open_folios { count }
VARIANCE_OVER_THRESHOLDVariance > tenant thresholdManager approval requiredManager approvesfrontend.eod.variance_over_threshold
MANAGER_APPROVAL_FAILEDWrong PIN / timeoutInline error / bannerRetryfrontend.eod.approval_failed
PRINT_FAILEDPrinter errorBanner with retryRetry / email insteadfrontend.eod.print_failed
EOD_ALREADY_SEALEDReplay attemptBanner; show existing sealed reportn/afrontend.eod.already_sealed

10. E2E Test Gates

  • Composite gate G-DESK-FIN-1: summary -> cash count -> variance (zero & non-zero) -> seal -> report.
  • Variance > threshold -> manager approval path.
  • Offline path -> reconnect -> seal reconciled.

11. Performance Requirements

MetricTarget
Summary mount<= 200 ms
Variance recompute<= 100 ms
Seal RTT (online)<= 1 s p95
Total flow<= 5 min wall-clock

12. Accessibility Requirements

  • All keyboard-completable.
  • Variance announcements via aria-live.
  • Manager PIN pad accessible.

13. Telemetry

Frontend events

  • frontend.eod.summary_viewed
  • frontend.eod.cash_counted { variance }
  • frontend.eod.variance_explained { reason }
  • frontend.eod.sealed { dayId }

Domain events emitted

  • melmastoon.eod.summary.generated.v1
  • melmastoon.eod.cash.counted.v1
  • melmastoon.eod.variance.recorded.v1
  • melmastoon.eod.sealed.v1
  • melmastoon.audit.recorded.v1

14. Success Criteria

  • Sealed EOD report has cryptographic hash; reconciles to ledger.
  • Variance documented and approved when non-zero.
  • Open folios at EOD surfaced and resolvable.
  • Reports printable + emailable; offline path proven.
  • Audit log captures who-did-what.

References