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

2.6 KiB

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.