Files
kooltab-backoffice/docs/architecture-decisions.md
T
2026-09-19 22:19:35 +02:00

2.3 KiB

Architecture Decisions

1. Registration Code Model

Decision: Added a RegistrationCode model to the database schema.

Rationale: The specification requires a registration-code mechanism. Rather than overloading an existing model or implementing a complex external system, a simple RegistrationCode table with venue scoping, expiration, and single-use semantics provides a clean implementation.

2. Payment Method Must Be Explicitly Selected

Decision: The UI never defaults to cash. The user must explicitly select a payment method.

Rationale: The specification explicitly forbids silent defaults. This prevents accidental charges and ensures compliance with the business requirement.

3. Cursor Implementation

Decision: Opaque cursor encoded as base64url containing timestamp + UUID tiebreaker.

Rationale: Provides a simple, privacy-preserving cursor that allows the server to determine which commands the device has already seen without exposing database internals.

4. Refresh Token Storage

Decision: Refresh tokens are stored hashed (SHA-256) in a RefreshToken table, supporting revocation and rotation.

Rationale: Provides security (tokens can be revoked) and aligns with OAuth2 best practices for refresh token management.

5. SQLite for Development

Decision: SQLite is the default development database.

Rationale: Zero configuration, fast for local development, and Prisma abstracts most differences. PostgreSQL migration path is documented in production.md.

6. No WebSockets

Decision: Dashboard uses polling (TanStack Query) instead of WebSockets.

Rationale: Simpler implementation, adequate for the expected update frequency (5-30 second intervals), and avoids WebSocket server infrastructure.

7. In-Memory Rate Limiting

Decision: Use NestJS ThrottlerModule with in-memory storage.

Rationale: Suitable for single-instance deployments. The abstraction allows swapping to Redis without controller changes.

8. Venue Isolation via JWT Claims

Decision: Venue ID is embedded in the JWT token. All service methods verify the requesting user/device's venue context rather than trusting URL parameters alone.

Rationale: Prevents cross-venue access even if a user manually modifies URL parameters.