-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Context
This project is undergoing a larger refactor of its business logic and database model.
The original implementation assumed a simple, atomic flow
(order → payment → ticket delivery).
Real-world usage revealed that this model is too rigid.
The goal of this refactor is not feature expansion, but:
- clearer separation of concerns
- flexible, explicit business rules
- delayed ticket rendering and finalization
- piece-wise payments and shipments
- strict separation between storage and business logic
Scope
- Database schema redesign
- Explicit payment, credit, shipment modeling
- Policy-based state derivation
- Decoupled domain services
Working Model (current)
This section describes the current high-level domain model.
It may be updated as the architecture evolves.
- Tickets are the smallest payable unit
- Payments are value-neutral
- Credits represent monetary state
- Ticket state is derived, never stored
- Shipment is the finalization boundary
- The database is a dumb, normalized storage:
domain state is represented via multiple ID-linked tables, without stored workflow or status semantics - Policies never access the database directly:
Data is loaded through repositories and assembled into use-case specific contexts. Policies operate exclusively on these contexts.
Work Packages
These work packages are not strictly isolated and may overlap.
Order reflects implementation intent, not a hard dependency graph.
-
WP1 – Database schema refactor
Explicit modeling of tickets, payments, credits, shipments and relations. -
WP2 – Policy layer
Implement read-policies (is_paid, is_shippable, …) and transition-policies (can_ship, can_cancel, …). -
WP3 – Offer service
Creation and handling of offers as non-binding purchase intents. -
WP4 – Payment service
Piece-wise, ticket-based payment finalization without implicit assumptions. -
WP5 – Shipment service
Shipment as explicit finalization step. -
WP6 – Check-in service
Entry validation based on derived ticket state. -
WP7 – Migration & cleanup
Remove legacy paths and dead code.
Decision Log (append-only)
This log records architectural decisions and direction changes.
Entries are never modified or removed.
- 2026-02-06:
- Business logic is strictly separated from storage. The database layer provides data access only; all state derivation and rules live in policies and services.
- The database schema was redesigned as a normalized, multi-table model with explicit ID-based relations to reflect domain concepts rather than workflow states.
- Tickets are defined as the smallest payable unit. Payments, offers and credits may span multiple tickets, but ticket payment finalization is always ticket-scoped.
- Payments are value-neutral. Monetary state is represented via credits, not payments themselves.
- Shipment is defined as the finalization boundary. After shipment, ticket-related payment assignments and cancellations are no longer allowed.
- Backward compatibility was explicitly abandoned in favor of a clearer and more flexible domain model.
- 2026-03-10:
- Policies never access the database directly:
Data is loaded through repositories and assembled into use-case specific contexts. Policies operate exclusively on these contexts. - Consequences:
- Business rules are isolated from persistence concerns.
- Policies can be tested using in-memory contexts.
- Database schema changes are localized to repositories and context builders.
- The architecture improves separation of concerns and maintainability.
- Policies never access the database directly:
How PRs relate to this issue
Each PR should reference:
Implements: WPx
Tracking: #2