Duplicate Tenant Detection

Status: Proposed Owner: @bilal Last Updated: 2026-02-15

Detect returning or known tenants when creating a new tenant record.

Trigger

On tenant creation, before save, check for soft-deleted tenants matching:

  • Phone (exact, E.164 normalised)
  • Email (exact, lowercase)
  • Match on either field, not both required

Scope

  1. Same property — “Returning tenant” (lived here before)
  2. Same organisation — “Known tenant” (lived at another property)

Warning UI

┌──────────────────────────────────────────────────┐
│  This person was previously a tenant              │
├──────────────────────────────────────────────────┤
│ Name: John Smith                                  │
│ Previous property: 123 High Street               │
│ Tenancy: 15 Mar 2023 → 20 Dec 2024               │
│ Issues reported: 7 (2 unresolved at move-out)    │
│ Priority: HIGH                                    │
├──────────────────────────────────────────────────┤
│ [Restore Previous]  [Create New Anyway]  [Cancel] │
└──────────────────────────────────────────────────┘

Actions

ActionBehaviour
Restore PreviousSet deletedAt: null, update propertyId, status → active
Create New AnywayNew tenant record, no link to history
CancelClose modal

Priority Flag Behaviour

Previous PriorityBehaviour
NORMALStandard warning
HIGHWarning highlighted amber
CRITICALRed highlight, require confirmation checkbox

Edge Cases

CaseHandling
Multiple matchesShow most recent first
Active match (not deleted)Error: “Tenant already exists at [property]“
Phone + email match different recordsShow both
Restoring to different propertyUpdate propertyId

Not in Scope (V1)

  • Fuzzy name matching
  • Blacklist/block functionality
  • Cross-organisation matching

Implementation

  • New GraphQL query duplicateTenantCheck
  • Frontend modal component
  • Restore mutation (extend updateTenant to handle deletedAt: null)
  • Snapshot openIssueCount on soft-delete (new field)