01Problem and objectives
The restaurant group's lunch customers either queued or phoned ahead. The counter wrote orders on paper, walk-ins went through a retail-style POS screen, and the kitchen cooked tickets in arrival order with no view of its own capacity.
| Objective | KPI | Baseline | Target |
|---|---|---|---|
| OBJ-01 Build an own digital ordering channel | Share of orders placed in the app or on the web | 0% | 30% or more |
| OBJ-02 Take the phone out of the rush | Phone calls between 11:45 and 13:30 per branch per weekday | 38 | 8 or fewer |
| OBJ-03 Have pickup orders ready on time | Pickup orders marked Ready before the end of their pickup minute | 71% | 92% or more |
| OBJ-04 Get customizations right | Orders remade or refunded for a wrong customization, per 1,000 orders | 18 | 5 or fewer |
| OBJ-05 Cut no-shows | Pickup orders Ready but never collected or paid, as a share of pickup orders | 4.2% | 1.5% or less |
| OBJ-06 Speed up the counter | Median walk-in transaction, first item to payment complete | 74 s | 50 s or less |
The hard parts are timing and consistency: offering only pickup times the kitchen can actually meet, never refusing a walk-in, pricing customised items without drift from the POS, and keeping the till and the boards in step when a connection drops.
02My role and approach
I ran the full lifecycle as the sole BA, from rush-hour observation to post-incident reviews. Each phase lists the documents it produced; click one to open it.
Discover
24 interviews, 8 rush-hour observation logs, a two-week call log, a three-month POS export, a customer survey and a build-or-buy scan.
Define
A BRD with six measurable objectives and an SRS with 72 FRs, 45 business rules in 8 decision tables and 28 NFRs.
Design
C4 architecture, three ADRs, ERD and data dictionary, process, sequence and state diagrams, five wireframes and a 42-operation OpenAPI contract with live-update events.
Deliver
Six two-week sprints for 42 stories and 203 points; seven change requests, two of them rejected with evidence.
Validate
90 test cases with decision tables and boundary values, and 12 UAT scripts signed by the product owner and a manager per branch.
Operate and improve
Two blameless reviews produced CR-004 and CR-007, then a Spec Kit spec for the rush-hour throttle in release 1.2.
03Inside the documents
Open any document below. It renders here from the repository, with the diagrams drawn live. The two anchor documents are also available as formatted PDFs.
04Designs
Five annotated wireframes: customising an item, choosing a pickup time, order status with the invoice, the iPad till with its live queue, and the kitchen board. Click any screen to enlarge it.
05Key decisions
These are the calls I would expect to defend in a design review.
Kitchen minutes, not 15-minute slots
A pickup minute is offered only if the order's kitchen minutes are free: ceil(units × minutes per unit × rush factor). Each kitchen minute is a database record with a unique index, so two orders can never hold it (ADR-001).
Walk-ins are never refused
The till can always overbook. Since release 1.2, online orders may hold only 9 of the 15 kitchen minutes in each rush quarter-hour until 20 minutes before it starts (CR-006, BR-018).
No credit for removed ingredients
Removing an ingredient never changes the price. Credits saved no cost and made prices drift from the POS articles.
Receipts stay with a certified POS provider
The platform never signs fiscal receipts. It raises one invoice per paid order in each branch's POS account through an outbox, and rounds VAT once per rate group, exactly as the POS does (ADR-003).
06Traceability explorer
Pick an objective, then a requirement, to follow its chain through business rules, stories, API operations and tests. The data comes from the generated traceability matrix in the repository.
07Worked example
One calculation runs through the whole document set with identical numbers: the SRS, the business rules, a story's acceptance criteria, the test cases and the test data.
08Incidents to requirements
Production incidents are where requirements prove themselves. Each review is blameless, with a timeline, 5 Whys and corrective actions, and it closes the loop with a change request.
| Incident | What happened | Requirement change |
|---|---|---|
| SEV-2 Till and board desync INC-2026-004 | After a router restart, both tills reconnected but never re-joined their live-update room and worked from a frozen queue for 40 minutes; three app orders were re-keyed as walk-ins and cooked twice. | CR-004: boards and tills resync after every reconnect |
| SEV-2 Duplicate card capture on retry INC-2026-009 | With the POS invoice call slow, card confirmations on the till timed out and Retry re-ran the card flow: 23 customers were charged twice, EUR 412.60 in total, all refunded. | CR-007: charge once, with tracked payment attempts, an invoice outbox and reconciliation |
09Tech stack
The stack documented in the architecture. As the BA I own the requirements it must satisfy, the integration contracts and the quality scenarios, not the code.
- Customer app and till
- Flutter (Dart) for iOS, Android and iPadOS
- Web ordering and admin
- React 18 with Redux
- API
- Node.js LTS, Express and Mongoose, OpenAPI 3.1 contract first
- Database
- MongoDB replica set with multi-document transactions
- Live updates
- Socket.IO with sequence numbers and snapshots per branch
- Jobs
- Node.js worker with a MongoDB-backed scheduler
- Receipts and invoices
- Cloud POS and invoicing provider, one account per branch
- Payments and notifications
- Card payment provider with SCA and a reader SDK; Firebase Cloud Messaging; transactional email
10Reflection
What worked. Modelling capacity as kitchen minutes rather than time slots. It made the rush-hour rules testable, gave the kitchen a number it recognised, and turned a vague "we get overwhelmed at lunch" into a decision table.
What I'd do next. Instrument the throttle introduced in release 1.2 for a month before tuning it, and test the till reconnect path on each branch's real network rather than a lab router.
