8. Backend & Frontend Interfaces
This section defines the application contract between the browser UI, terminal flows, NFC card payloads, and the backend service. It is written as a practical developer reference for building the app with TanStack Start on the frontend and Nitro on the backend.
Purpose
- Make frontend, terminal, and backend responsibilities explicit.
- Keep the card format and API behavior stable and easy to implement.
- Provide a shared reference for developers and documentation readers.
Frontend architecture
- Build the app using TanStack Start conventions: routing, query caching, and state management.
- Use Web NFC to interact with the card and Web Crypto to validate encryption and authentication.
- Show clear workflows for reading card details, creating transactions, and reconciling offline events.
- Store temporary offline events in browser-managed storage (IndexedDB or localStorage) when backend access is unavailable.
- Support two UI modes:
- Member view: read-only balance, history, and card status.
- Terminal mode: write-enabled flow for transactions, check-ins, and reconciliation.
Backend architecture
- Run as a Nitro-compatible service with API routes for session grants, policy data, reconciliation, and audit logging.
- Issue and rotate session grants and key versions.
- Authenticate terminals, manage risk rules, and validate high-risk operations.
- Reconcile offline card events and persist operational logs.
- Expose a stable API that frontend and terminal code can depend on.
Interface contracts
Session grants
- Issued by the backend with
keyVersion, expiry, permitted operations, and backend signature. - Kept temporarily by terminals; never stored permanently on the card.
- Validated by the frontend before allowing any state-changing write.
Card payloads
- Include current balance, status, replay counter, session pointer, and authentication trailer.
- Are read by the frontend and validated locally before the app makes decisions.
- Are rejected as suspicious if cryptographic validation fails.
API endpoints
Full endpoint definitions — payloads, error codes, and constraints — are in the API Spec:
| Endpoint | Section |
|---|---|
POST /api/auth/token | API Spec §2 Authentication |
GET /api/session-grant | API Spec §3 Session Grants |
GET /api/policy | API Spec §4 Policy |
POST /api/cards | API Spec §5 Cards |
GET /api/cards/:cardId | API Spec §5 Cards |
POST /api/cards/:cardId/topup | API Spec §5 Cards |
POST /api/cards/:cardId/block | API Spec §5 Cards |
POST /api/cards/:cardId/reissue | API Spec §5 Cards |
POST /api/reconcile | API Spec §6 Reconciliation |
POST /api/terminal-report | API Spec §7 Terminal Reports |
Terminal behavior
- Confirm card state and status before every transaction.
- Enforce status, session, and risk rules in the terminal workflow.
- Use the A/B buffer process for safe card writes.
- Queue reconciliation events and upload them when backend connectivity is restored.
UX guidance
- Display simple, user-facing messages such as
Card blocked,Session expired,Pending reconciliation, andInvalid card state. - Hide low-level cryptographic details from users.
- Keep terminal, station, and gate flows consistent across screens.
Developer guidance
- Keep schema and interface definitions aligned between frontend and backend.
- Prefer shared type generation or schema references (e.g., Zod schemas or OpenAPI types) to avoid frontend/backend drift.
- Document all card field or API schema changes in the spec before deployment.
- Treat the frontend as the canonical place for card validation logic, with backend policies used for trusted decisions and session management.