Property Activity Events

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

Comprehensive activity log for properties — every significant event in one timeline.

Problem

Need to show “everything that ever happened at this property”:

  • Tenant additions, updates, removals
  • Property field changes
  • Document uploads, expirations
  • Issues created with status changes

Currently IssueEvent exists for issue-level changes, but nothing for property-level or tenant-level activity.

Decision: Separate PropertyEvent Table

Keep IssueEvent as-is, add a new PropertyEvent table. Rationale:

  1. No migration risk to existing IssueEvent
  2. Property-centric summary view (drill into issue for detail)
  3. FK constraints + Prisma type safety
  4. Simpler queries

Event Types

CategoryEvents
PropertyCREATED, UPDATED, DEACTIVATED, REACTIVATED, PRIORITY_CHANGED
TenantADDED, UPDATED, REMOVED, STATUS_CHANGED
DocumentUPLOADED, UPDATED, DELETED, EXPIRED
IssueREPORTED, STATUS_CHANGED, RESOLVED, CANCELLED, VENDOR_ASSIGNED

Activity Log UI

┌─────────────────────────────────────────────────┐
│ Activity                                 Filter  │
├─────────────────────────────────────────────────┤
│ Today                                            │
│ ├─ 14:32  Issue resolved: "Boiler not working"  │
│ ├─ 11:15  Document uploaded: Gas Safety Cert     │
│ └─ 09:00  Tenant added: John Smith (Room 3)     │
│ Yesterday                                        │
│ ├─ 16:45  Issue reported: "Boiler not working"  │
│ └─ 10:30  Priority changed: Normal → High        │
│                     [Load more]                  │
└─────────────────────────────────────────────────┘

Schema

model PropertyEvent {
  id            String              @id @default(uuid())
  propertyId    String              @map("property_id")
  eventType     PropertyEventType   @map("event_type")
  actorId       String?             @map("actor_id")
  relatedEntity RelatedEntityType?  @map("related_entity")
  relatedId     String?             @map("related_id")
  previousData  Json?               @map("previous_data")
  newData       Json?               @map("new_data")
  summary       String?             // Human-readable
  createdAt     DateTime            @default(now())
 
  property      Property            @relation(...)
  actor         User?               @relation(...)
 
  @@index([propertyId, createdAt(sort: Desc)])
  @@map("property_events")
}

Implementation Plan

  1. Phase 1: Schema + basic logging (property, tenant, document, issue mutations)
  2. Phase 2: GraphQL type + paginated query + Activity UI component
  3. Phase 3: Filtering, actor display, click-through, real-time updates

Open Questions

  • Retention policy — keep forever or archive after X months?
  • Backfill — generate historical events from existing data?
  • System events — how to attribute automated actions?