Files
MobilityOps/docs/04-domain-model.md

119 lines
2.6 KiB
Markdown

# Domain model
Use UUID primary keys internally. Human-facing references are immutable unique strings.
## User
- id
- public_ref (`USR-...`)
- display_name
- role: `operations_manager | rental_employee`
- active
## Customer
- id
- public_ref (`CUS-0001`)
- first_name, last_name
- email, phone
- postal_code, city
- date_of_birth (optional)
- merged_into_customer_id (optional)
- created_at, updated_at
## Vehicle
- id
- public_ref (`MO-001`)
- make, model, model_year
- registration_number
- location
- operational_status: `available | rented | cleaning | maintenance | blocked`
- odometer_km
- next_service_km
- active
- version for optimistic concurrency
## Booking
- id
- public_ref (`BK-...`)
- customer_id, vehicle_id
- starts_at, ends_at
- status: `reserved | active | returned | cancelled | blocked`
- start_odometer_km, end_odometer_km
- requirements_complete
Database invariant: active/reserved bookings for the same vehicle may not overlap after validation. A deliberate seeded conflict may be imported as an external-data quality issue through a controlled bypass, never created through the normal command API.
## Inspection
- id
- public_ref
- booking_id, vehicle_id
- type: `checkout | return`
- fuel_level_percent
- cleanliness_ok
- damage_reported
- technical_warning
- notes
- odometer_km
- completed_at, completed_by
## MaintenanceRecord
- id
- vehicle_id
- occurred_at
- odometer_km
- category
- summary
## DataQualityIssue
- id
- public_ref
- rule_type:
- `possible_duplicate_customer`
- `missing_required_field`
- `odometer_regression`
- `booking_overlap`
- `vehicle_status_conflict`
- entity_type, entity_id
- severity: `low | medium | high`
- status: `open | deferred | resolved | rejected`
- evidence_json
- proposed_action_json
- detected_at, resolved_at, resolved_by
## OutboxEvent / WorkflowRun
- id / event_id
- event_type
- aggregate_type, aggregate_id
- payload_json
- occurred_at
- delivery_status: `pending | delivering | succeeded | failed`
- attempts, next_attempt_at, last_error
- external_run_id
## AuditEvent
- id
- actor_type: `user | service | system`
- actor_id / actor_label
- action
- entity_type, entity_id
- correlation_id
- before_json, after_json, metadata_json
- occurred_at
## Required invariants
- a vehicle return cannot reduce the canonical odometer;
- a return with a lower submitted reading is recorded as an inspection and issue, while canonical odometer remains unchanged;
- damage or a critical warning blocks the vehicle;
- merged customers remain as tombstones linked to the survivor;
- resolving a quality issue and applying its correction is transactional and audited;
- public references never change after creation.