Skip to content

[HARD][LOANS] Implement guarded loan and vehicle lifecycle state machines #85

Description

@Obiajulu-gif

Overview

Replace ad-hoc status updates for loans, vehicles, and investments with explicit, validated domain state machines.

Problem

The current schemas expose status strings but do not centrally define which transitions are valid, who may perform them, or which side effects must occur. Invalid transitions can activate an unfunded loan, reassign a financed vehicle, complete a loan with arrears, or bypass required approvals.

Scope

  • Define transition maps for Loan, Vehicle, and Investment states.
  • Create service commands such as submit, start review, approve, reject, activate, complete, cancel, reserve vehicle, assign driver, enter maintenance, and retire.
  • Enforce role/permission checks and transition preconditions.
  • Execute related updates atomically across loan, vehicle, investment, contract, ledger/transaction, and audit records.
  • Add transition history with actor, reason, previous state, next state, timestamp, and correlation ID.
  • Prevent direct route-level status mutation outside the domain service.
  • Add a migration/check script for existing records in impossible combinations.

Required invariants

  • A loan cannot become active until funding and down-payment requirements are met.
  • A vehicle cannot be assigned to multiple active contracts.
  • A completed loan cannot accept ordinary repayments.
  • Rejected/cancelled records cannot silently return to active states.
  • Administrative overrides require a reason and audit event.

Test requirements

  • every allowed and forbidden transition
  • role-specific authorization
  • concurrent transitions from the same starting version
  • rollback when a side effect fails
  • migration detection of impossible legacy combinations
  • transition history completeness

Acceptance criteria

  • All status changes flow through typed domain transition services.
  • Invalid or stale transitions return clear conflict errors.
  • Related records update in one database transaction.
  • Transition history is immutable and queryable.
  • Existing invalid data can be reported and repaired safely.
  • Documentation includes state diagrams and transition tables.
  • Lint, typecheck, tests, and build pass.

Difficulty

Hard

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions