Tenancy Dispute Entry: State Machine Cascade
Tenancy Dispute Entry: State Machine Cascade
Overview
When a tenancy is marked as disputed, the platform automatically executes a cascade of state transitions and notifications across all related entities. This ensures consistency across deposit releases, compliance records, and stakeholder communications — with no manual steps required.
Trigger
The cascade is initiated by the internal event:
tenancy.status_changed → new status: "disputed"
This event is emitted by any part of the system that updates a tenancy's status to disputed — whether via the UI, an API call, or another automated workflow.
Cascade Sequence
Step 1 — Locate the Active Deposit Release
The function queries deposit_releases to find the active release record associated with the tenancy. If no active release is found, the cascade halts and logs an audit entry.
Step 2 — Transition Deposit Release to disputed
If the active deposit release is not already in disputed status, its status is updated:
deposit_releases.status = 'disputed'
This transition is idempotent — if the record is already disputed, no write is performed.
Step 3 — Upsert Compliance Check
A compliance_checks row is created or updated for the tenancy with the following attributes:
| Field | Value |
|---|---|
rule | tenancy_in_active_dispute |
severity | critical |
status | active / unresolved |
The upsert pattern prevents duplicate rows if the event fires more than once.
Step 4 — Send Urgent Notifications
Urgent notifications are dispatched to the following recipients:
- All organisation admins associated with the tenancy's organisation
- All organisation owners
- The assigned property manager for the property
Notifications are recorded in the notifications entity and surfaced in the platform's notification centre.
Step 5 — Fire depositRelease.disputed Event
To avoid duplicating logic, the cascade emits:
depositRelease.disputed
This event is consumed by the existing disputed-deposit-release workflow, which handles the downstream processing for the release itself (e.g. timeline updates, evidence collection prompts, resolution workflows).
Entity Reference
| Entity | Role in Cascade |
|---|---|
tenancies | Source — dispute status read from status_changed event |
deposit_releases | Updated to disputed status (idempotent) |
compliance_checks | Upserted with rule tenancy_in_active_dispute at critical severity |
notifications | Urgent alerts created for admins, owners, and property manager |
audit_log | All cascade actions are recorded for traceability and compliance |
Idempotency & Safety
- Deposit release transition checks current status before writing — safe to re-trigger.
- Compliance check upsert uses a single row per rule per tenancy — no duplicates created.
- Downstream event delegates to an existing workflow rather than re-implementing logic, ensuring a single source of truth for disputed-release processing.
Related Workflows
- Disputed Deposit Release Workflow — triggered by
depositRelease.disputed; handles the release-level resolution process. - Compliance Review Queue — surfaces critical
compliance_checksrows to compliance managers. - Notification Centre — displays urgent notifications to admins, owners, and property managers.