System design
How the leasing assistant is put together.
Business rules, workflow, and conversation are engines outside React. The UI reads them; it does not own them. Every integration sits behind a port with a mock, so Mioym Affordable Homes can run the workflow before a single credential exists.
Workflow stages
Derived from services/workflow — this list cannot drift from the engine.
Qualification rules
Configured in services/rules. Thresholds are data, not code.
Tour preference collected
Date and time required
Minimum credit score
600 or above
Income details
Annual and monthly required
Employment status
Employed or self-employed
Move-in date
Date provided
Property availability
Unit still available
Pet preference
Within property pet policy
Integrations
Ports, adapters, and what backs them
Each integration is an interface with a working mock. Swapping in a real provider is a container change, not a rewrite.
| Port | Mock | Live today | Production target |
|---|---|---|---|
| CrmPort | In-memory map | Airtable | Freshworks |
| LlmPort | Deterministic rules | OpenAI · Anthropic · Gemini | Any provider |
| CalendarPort | Fixed inventory | Calendly | MS Bookings |
| EmailPort | Console log | n8n → Gmail | Outlook · SendGrid |
CRM schema
Leads
Contact, source, stage, qualification, door code, ingestion completeness
Activities
Timeline events and notification deliveries, batched per lead
Tours
Reserved slot, duration, door-code issuance, cancellation
Emails
Send history: template, recipient, status, provider message id
Properties
Address, unit, availability
Conversation memory
What Sophie remembers
Context carries across every channel, so a question already answered is never asked twice.
Voice agent
Prepared, not yet built
Post-tour follow-up by AI phone call is in the client's scope. The conversation engine is channel-agnostic, so voice reuses the same turn contract.