# PropertyLab AI — Appointment Engine (Agent Leader Console)
## Build specification for Claude Code

**Version:** 1.0 · Build brief for the first production release
**Audience:** Claude Code (implementation agent)
**Deliverable:** A clickable, high-fidelity, production frontend for the agent-leader console — wired to the existing PETA backend. **No mock data.**

---

## 0. How to use this document

This is a build brief, not a finished design. Read it top to bottom once before starting.

**Two sections are load-bearing — read them first and let them govern everything:**
- **§10 Ways of working (MANDATORY)** — *how* to build: one slice at a time, depth-first, wired to real data, verified before the next. This is how you avoid shallow scaffolding. Non-negotiable.
- **§4A SaaS multi-tenancy & roles** — this is a multi-tenant SaaS product; every query and write is tenant-scoped and role-gated. Tenant isolation is a hard security requirement.

**Before writing any frontend code, do this first:**

1. **Locate and read the existing PETA backend spec / codebase.** This console is a new surface on top of an existing system (PETA — the PropertyLab CRM + AI product suite). The Retell AI caller, the WhatsApp automation, the Meta integration, the tenancy/org model, and RBAC are already built and running inside PETA. Find the backend's API contract (REST/GraphQL schema, service definitions, DB models, or existing API docs) and **align every data structure, the tenancy model, and the WhatsApp/Meta connection mechanism in this console to what already exists**. Do not invent new field names, new tables, new tenancy, or new connection schemes where PETA already defines them.
2. **Produce a short data-mapping note** (`DATA-MAPPING.md`) before building: for each screen in §5, list which existing PETA entities / endpoints feed it, how it is tenant-scoped, and flag any gap where the backend does not yet expose what a screen needs. Surface those gaps to the human rather than faking the data.
3. **Create `BUILD-PROGRESS.md`** (§10.5) listing every slice from §9 with its Definition-of-Done checklist.
4. Only after the mapping is agreed, build the frontend — **one slice at a time per §10**, tenancy + auth foundation first.

If any instruction here conflicts with the established PETA backend contract, **the backend wins** — match it and note the deviation.

---

## 1. Product context (why this exists)

### The business model this console serves
A typical Malaysian property agency runs like this:
- An **agent leader** runs Meta (Facebook/Instagram) ads for their team.
- Leads click through to WhatsApp; **agents** then WhatsApp and call each lead to set a **showroom appointment**.
- Commission splits three ways: **ads 40% · appointment 20% · closing 40%.**

This product replaces the human labour behind the **appointment 20%** — the calling and WhatsApp follow-up — with AI (Retell AI caller + WhatsApp automation). The agent leader then keeps a larger share (the 20% that used to pay the appointment-setter), moving their cut from 40% toward ~60%.

### The core value proposition the UI must sell
Two things, in priority order:

1. **No leakage.** Manual follow-up leaks badly: leads that arrive at night, leads never retried after one missed call, leads dropped after one or two touches, promised callbacks forgotten. Every leaked lead is ad spend already paid for. The AI works **every** lead, **every** time, within seconds.
2. **Lower cost, same or better outcome.** The leader stops paying the 20% appointment cut and still gets appointments booked into the showroom.

The person paying for and opening this console every day is the **agent leader**. Design for them. (A separate, slimmer *closing-agent* view is out of scope for this release — see §7.)

### CRITICAL: honesty rule on the "no leakage" claim
The product is launching to **new customers with no historical baseline**. We therefore **cannot** claim counterfactual numbers like "recovered 129 of 147 leads that would have leaked" — there is no data to prove what manual follow-up "would have" lost, and a fabricated number destroys trust the moment the customer asks where it came from.

**The console must only ever display metrics derived from the system's own live activity logs.** Frame the value as **coverage / guarantee**, not **recovery**:

- ✅ Allowed (verifiable from run logs): "312 of 312 leads worked", "0 dropped", "avg time to first contact: 41s", "100% of follow-ups sent on schedule", "58 leads worked outside 9–5".
- ❌ Forbidden (no baseline exists): "X leads recovered", "would have leaked", "manual follow-up would have lost X", any % improvement vs a manual baseline.

Once a customer has accumulated their own historical data over time, trend comparisons against *their own past* become legitimate. That is a later release, not this one. **Do not hardcode or invent any baseline comparison in this build.**

---

## 2. Design language

### Brand
- **Primary ink:** `#0E1B33` (used for sidebar, primary text, dark surfaces)
- **Primary blue:** `#1E6FE0` (primary actions, active nav, accents)
- **Dark-mode blue:** `#4D9BFF`
- Logo mark: house outline with three ascending analytics bars inside; wordmark "Property" in ink + "Lab" in blue. Provide the mark as an inline SVG component.

### Suggested palette tokens (define as CSS variables / Tailwind theme; adjust to house tokens if PETA already has a design system — reuse PETA's if it exists)
```
--ink:#0E1B33  --ink-2:#1B2C4A
--blue:#1E6FE0 --blue-dark:#4D9BFF --blue-soft:#EAF2FE --blue-softer:#F5F9FF
--bg:#F6F8FB   --surface:#FFFFFF   --surface-2:#FBFCFE
--line:#E6EBF2 --line-2:#D8E0EC
--text:#0E1B33 --text-2:#5A6B85    --text-3:#8A98AE
--green:#12A150 (bg #E7F6ED)   --amber:#C77700 (bg #FCF1DD)
--red:#D8452B (bg #FBEAE6)      --purple:#6A4AC9 (bg #EEEAFB)
--radius:10px  --radius-lg:14px
```

### Aesthetic rules
- Flat, clean, white surfaces on a light-gray canvas. Hairline borders (1px, `--line`). Generous whitespace. Soft shadows only (`0 1px 2px`, `0 4px 16px` at low opacity). No heavy gradients except the two dark/green hero bands.
- Font: a modern sans (Inter or system UI equivalent); a monospace for phone numbers, durations, IDs, and code-like values.
- **Sentence case** everywhere. No ALL CAPS, no Title Case except proper nouns.
- Colour encodes meaning, not decoration: green = healthy/on-track/appointment; amber = pending/attention; red = at-risk/refused/hot-lead; blue = informational/AI-in-progress; purple = AI-authored content (call/chat by the AI).
- **Dark mode:** implement it. All colours must work on a near-black canvas. Prefer semantic tokens over hardcoded hex in components.

### Responsive (both desktop and mobile are first-class)
- Desktop: fixed left sidebar (~236px) + top bar + scrollable content.
- ≤1000px: sidebar collapses to an off-canvas drawer opened by a hamburger in the top bar, with a scrim overlay.
- ≤640px: tighten padding; hide non-essential table columns (keep the identifying + status columns); stack two-column layouts into one.
- The WhatsApp review screen and the AI-calling screen are master-detail: on mobile, show the list first, tapping an item swaps to the detail with a back affordance.
- Meet a quality floor: keyboard focus visible, `prefers-reduced-motion` respected, tap targets ≥40px.

---

## 3. Information architecture

Left sidebar navigation, grouped:

```
Overview
  • Dashboard
  • Coverage            (the "no leakage" proof screen)
Leads
  • Leads               (list → Lead detail)
  • WhatsApp review
  • AI calling
Manage
  • Campaigns           (Meta Ads integration)
  • Agent allocation
  • Automation          (workflow + script + knowledge base)
  • Content library      (per-project knowledge / scripts / WhatsApp sequences — §5.8)
  • Upload & integrate   (AI ingestion: drop documents, auto-classify + wire in — §5.11)
Settings                (Owner/Admin)
  • Connections         (tenant's WhatsApp Business + Meta Ads — §5.12)
  • Team & roles        (invite leaders/agents, assign roles — §5.12)
  • Billing             (subscription — §5.12)
```

Sidebar footer: current leader's identity (avatar, name, "Team Leader" role) + settings entry.
Top bar per page: page title + one-line subtitle, a live status pill ("AI caller live"), a date-range control, and an export action.

Live status and any real-time counts (leads in retry, live calls, unread WhatsApp) should reflect real backend state — see §4 on realtime.

### Page roles — do not overlap them
Three screens answer three different questions. Keep the split clean; don't duplicate one screen's job in another.

| Screen | The question it answers | Data shape |
|---|---|---|
| **Dashboard** | "How is today overall, and what needs me right now?" | Aggregate totals + an action queue |
| **Leads** | "How is the AI performing across all leads, and exactly where does each individual lead stand right now?" | Per-lead status for the whole book, filterable by stage |
| **Coverage** | "Is the system dropping any lead I paid for?" | Coverage / no-miss proof only, from run logs |

Concretely: a leader asking *"how many leads, how many appointments, how many still in follow-up, and what is the status of each lead right now"* is answered on the **Leads** screen (via the pipeline status bar + the per-lead table + Lead detail), **not** on Coverage. Coverage deliberately does one narrow job — prove nothing leaks — because it doubles as the sales-proof screen. Dashboard gives the daily summary and the to-do queue. Leads is the operational source of truth for per-lead status.

---

## 4. Data layer & backend integration

### Golden rule
**Every screen renders real data from the existing PETA backend.** There is no mock/fixture layer in the shipped product. During development you may stub a screen behind a typed data-access module, but the stub must be a thin, clearly-marked adapter that is replaced by the real call before that screen is considered done — not fake data baked into components.

### Integration approach
1. Read the PETA backend contract first (§0). Reuse its auth, its lead model, its campaign model, its call + message records.
2. Implement a single typed **data-access layer** (e.g. `/lib/api/*` or generated GraphQL/REST client) that the UI consumes. UI components never call `fetch` directly.
3. Map the domain objects below to PETA's actual entities. The names below are the *console's* vocabulary; bind them to whatever PETA already calls them.

### Domain objects the UI needs (bind to existing PETA entities)
- **Tenant** — the account boundary (agency or solo). Owns all data below. Bind to PETA's existing org/workspace entity. See §4A.
- **User** — a person in a tenant with role(s) Owner/Admin · Leader · Agent. Bind to PETA's user + RBAC. See §4A.
- **Connection** — a tenant's linked WhatsApp Business account and Meta Ads account (status, bound number / ad-account, health, last sync). Bind to PETA's existing integration + credential storage. See §4A.
- **Lead** — id, display name, phone, source campaign, project, current pipeline stage, AI-captured qualification (intent: investor / own-stay / upgrader; budget; timeline), **buying-journey stage** (`buyingJourneyStage` enum + `selfReportedFirstProperty` + `systemObservedViewings` — see §5.9), lead score, timestamps (created, first-contacted, last-activity), next scheduled action, assigned agent. *(Tenant-scoped; visible to an Agent only if assigned to them.)*
- **PipelineStage** — the ordered funnel the backend already uses. The console assumes stages roughly like: `New → AI called → Answered → Appointment → Showed up → Closed → Lost`. **Use PETA's real stage enum**; adapt labels/colours to it rather than forcing these.
- **Campaign** — id, name, project, platform (Meta), status (active/paused), spend, leads count, cost-per-lead, appointments count, ROAS. Sourced from the Meta Ads integration PETA already has (or via PETA's stored campaign records).
- **CallRecord** (Retell) — id, lead ref, timestamp, duration, connection result (answered / no-answer / voicemail), outcome (appointment / callback / no-appointment / refused), sentiment, recording URL, transcript (turn-by-turn with speaker), post-call structured analysis (intent, budget, timeline, **buying-journey / first-property answer**, objection, do-not-call flag).
- **MessageThread + Message** (WhatsApp) — thread per lead; messages with direction (inbound / AI-outbound / human-outbound), body, timestamp, delivery state, and whether a given AI reply is pending a lead response. Must distinguish AI-authored vs human-authored messages.
- **Agent** — id, name, avatar/initials, close rate, active-lead count, **tier/seniority** (for training-vs-close routing — add if PETA lacks it; close rate can proxy).
- **Workflow** — the automation definition: an ordered set of steps (nodes) with fixed structure for this release; each node carries editable content (script text, attached knowledge-base items, parameters). See §5.7.
- **Project** — the deal being sold (pilot: Armani Hallson); content (knowledge, scripts, WhatsApp sequences) is scoped per project. See §5.8.
- **KnowledgeItem / Script / WhatsAppSequence** — the AI content per project: knowledge-base Q&A/fact-sheets, calling scripts, and ordered WhatsApp step sequences (with media). Uploaded and parsed via §5.8, attachable to workflow nodes.
- **IngestionJob** — an AI document-ingestion run (§5.11): the uploaded file(s), each document's detected type + confidence, the extracted/structured result, the AI's suggested improvements (for scripts), the proposed integration targets, and the leader's accept/edit/reject decisions. Versioned and reversible on activation.
- **RoutingRule** — editable rules mapping buying-journey stage + budget + intent → agent tier (§5.9/§5.10).
- **CoverageMetrics** — derived entirely from activity logs: counts of leads worked, time-to-first-contact distribution, follow-ups-on-schedule rate, retries honoured, after-hours contacts, promised-callbacks honoured. **No baseline/counterfactual fields.**

### Realtime
Where PETA supports it (websocket/subscription/polling), reflect live changes: new leads arriving, calls going live/completing, new WhatsApp messages, stage transitions. If PETA has no realtime channel, fall back to sensible polling on the dashboard, calling, and WhatsApp screens, and note it in `DATA-MAPPING.md`. Do not simulate fake live activity.

### Writes the console must perform (verify these exist in PETA before wiring)
- Assign / reassign a lead to an agent.
- Take over a WhatsApp thread from the AI (pause AI auto-reply) and hand back.
- Flag a lead/thread for human agent attention.
- Edit a workflow node's script, its attached knowledge items, and its parameters; save a new workflow version.
- Pause / resume a campaign (if PETA exposes Meta control; otherwise deep-link into Meta and mark read-only).
- Export the current view (CSV/PDF) — client-side generation is acceptable if no backend export exists.

If any write above is not supported by the backend yet, render the control in a clearly disabled/"not yet available" state and list it in `DATA-MAPPING.md` — do not fake success.

---

## 4A. SaaS multi-tenancy, roles & per-tenant connections

This is a **multi-tenant SaaS product**, not a single-team tool. Every screen, query, and write in this spec operates **inside a tenant boundary**. Get this wrong and one customer sees another customer's leads — the single most serious failure mode. Treat tenant isolation as a hard security requirement, not a feature.

### Tenancy model
- A **tenant** is the top-level account boundary. Two shapes, one architecture:
  - **Agency tenant** — one agency = one tenant, containing multiple leaders and multiple agents.
  - **Solo agent tenant** — an individual using it alone is simply a tenant of one (they hold owner + leader + agent capabilities themselves). No separate code path — the same tenant model at n=1.
- All domain data (leads, campaigns, calls, WhatsApp threads, workflows, content, agents, routing rules, coverage metrics, ingestion jobs — everything in §4) is **owned by a tenant** and must carry a tenant scope. Every read and write is filtered by the current tenant, server-side. The client never sees cross-tenant data even if it asked.
- **Align to PETA's existing tenancy.** PETA almost certainly already has an organisation/workspace/account concept and row-level scoping. **Reuse it** — bind "tenant" to PETA's existing org/workspace entity and its isolation mechanism. Do not invent a parallel tenancy scheme. Confirm in `DATA-MAPPING.md` how PETA scopes data and that every query in this console inherits it.

### Roles (RBAC — three roles)
Bind these to PETA's existing RBAC if it has one; otherwise implement them. A user belongs to a tenant with one (or more) of:

| Role | Can do | Cannot |
|---|---|---|
| **Owner / Admin** | Everything a Leader can, **plus**: billing/subscription, tenant settings, connect & manage the tenant's WhatsApp Business and Meta accounts (§ below), manage users (invite leaders/agents, assign roles) | — |
| **Leader** | Run campaigns, see the whole team's leads/pipeline/coverage, WhatsApp review, AI calling, agent allocation, automation, content library, AI ingestion — i.e. all of §5 **for their team's data** | Billing, connecting the tenant's WhatsApp/Meta accounts, managing users |
| **Agent** | See **only their own** assigned leads and appointments, their own lead detail, and the WhatsApp/call records for their own leads | See other agents' leads, team-wide dashboards, campaigns, allocation, automation, content, ingestion, settings, billing |

- Enforce role checks **server-side** on every endpoint, not just by hiding UI. Hidden-but-reachable data is a breach.
- The console in this spec is primarily the **Owner/Leader** surface. An **Agent** logging in sees a scoped-down view (their own leads + appointments only) — this overlaps with the out-of-scope closing-agent app (§7); for this release, at minimum an Agent must not be able to reach team-wide data. Build the role gate now even if the full agent experience comes later.
- In a **solo tenant**, the single user holds all three roles — the UI shows the full surface without needing other users.

### Per-tenant WhatsApp & Meta connections (self-serve)
Each tenant connects **their own** official WhatsApp Business account and **their own** Meta (Facebook/Instagram) Ads account from inside the product. A tenant's automation runs on *their* WhatsApp number and pulls *their* ad campaigns — never a shared or hardcoded credential.

- **Reference PETA's existing WhatsApp + Meta integration code.** The Retell + WhatsApp automation and any Meta ingestion already exist in PETA; **this console reuses PETA's connection mechanism and credential storage** rather than building a new one. Before building the settings UI, read how PETA:
  - authenticates and stores a WhatsApp Business account (WABA / phone number / token / webhook),
  - authenticates and stores a Meta Ads account (OAuth app, ad-account id, page, access token, CTWA setup),
  - scopes those credentials to an org/tenant.
  Bind the settings screen to that. Document it in `DATA-MAPPING.md`.
- **Connection settings screen** (Owner/Admin only): per tenant, show connection status for WhatsApp Business and Meta Ads, with a self-serve **connect** flow (OAuth where the provider supports it — Meta Login / WhatsApp embedded signup — or a guided credential entry matching PETA's method), health/last-sync indicators, disconnect/reconnect, and which WhatsApp number / ad account is bound. Never display raw secrets.
- **Everything downstream keys off the tenant's own connection:** the WhatsApp review screen shows conversations on the tenant's number; Campaigns pulls the tenant's Meta campaigns; the automation sends from the tenant's WhatsApp; AI ingestion wires content into the tenant's caller/WhatsApp setup. If a tenant hasn't connected yet, gate the dependent screens with a clear "connect your WhatsApp / Meta account to begin" empty state — do not show mock data or another tenant's data.
- If OAuth self-serve isn't yet exposed by PETA's backend, implement the settings UI against PETA's existing credential mechanism and mark the fully self-serve OAuth step as pending in `DATA-MAPPING.md` — do not fake a connected state.

### What this means for every page in §5
- Every list/query is tenant-scoped (and agent-scoped for the Agent role).
- Onboarding order matters: a brand-new tenant first connects WhatsApp + Meta (Owner) and loads project content (§5.8/§5.11) before leads flow. Handle the empty/not-yet-connected states on every screen accordingly.
- Add a tenant switcher only if a user can belong to multiple tenants (confirm against PETA); otherwise the current tenant is implicit from the session.

---

## 5. Page specifications

Build in this order. Each page lists its purpose, layout, components, the data it needs, and the interactions. All numbers shown are examples of *shape*, not values to hardcode — pull real values.

### 5.1 Dashboard
**Purpose:** The leader's daily home. First glance must answer "is the money working, and is anything being dropped?"

**Layout (top to bottom):**
1. **Stat row** — 4 metric cards, responsive grid:
   - **Commission saved** (hero, green) — the value of the appointment-cut (20%) the AI replaced this period. *This is the #1 reason they pay; it goes first, largest, green.* (See §6 for how this is computed — it must be defensible, or presented as a clearly-labelled projection with the formula visible, not a magic number.)
   - Leads in (+ cost per lead)
   - AI appointments (+ % of leads)
   - Showed up (+ show rate)
2. **Coverage band** (dark hero) — "N of N leads worked — 0 dropped", subtitle "Every lead contacted within X seconds. Every follow-up on schedule." Button → Coverage page. **All from live logs; no baseline claims.**
3. **Two-column:**
   - **Lead pipeline** funnel — horizontal bars for each stage with counts, descending. Uses PETA's real stage sequence.
   - **Needs your attention** — a short action list, each row deep-links to the relevant screen: hot leads waiting (AI-flagged cash/high-intent buyers needing a human), leads in retry loop, leads in WhatsApp nurture, appointments today needing assignment.
4. **Today's appointments** table — lead, time, intent, budget, assigned agent (or an "Assign" button if unassigned), status. Row → Lead detail.

**Data:** CoverageMetrics, pipeline counts by stage, today's appointments (Leads filtered by appointment date = today), attention queues (derived from lead flags/stages), commission-saved figure (§6).

### 5.2 Coverage  (the "no leakage" proof screen)
**Purpose:** Prove, from the system's own logs, that no paid-for lead goes untouched. This replaces any "leakage recovery" framing.

**Layout:**
1. **Stat row:** Leads worked (N/N, 0 dropped — green hero) · Avg time to first contact · Follow-ups on schedule (%) · Worked outside 9–5 (count).
2. **Coverage guarantees** list — each row is a rule the system enforced on every lead, with a count and a 100%-style bar: contacted within 60s (N/N), after-hours leads called next window, no-answer leads retried on schedule, promised callbacks honoured, follow-ups sent on time. Every figure from activity logs.
3. **Time-to-first-contact distribution** — buckets (under 1 min / 1–5 min / over 5 min out-of-hours) with counts.
4. **Methodology note** (must be present, verbatim intent): explain that every figure is from the system's own activity log with real timestamps; that we deliberately do **not** estimate what manual follow-up "would have" lost because it can't be proven; and that the gap versus manual handling is one the leader already knows from running their team.

**Data:** CoverageMetrics only. If a metric can't be sourced from logs, omit it — never approximate.

### 5.3 Leads (list) → Lead detail
**List purpose:** This is the leader's operational source of truth — it answers *"how is the AI performing across all my leads, how many are at each stage, how many are still in follow-up, and exactly where does each individual lead stand right now?"* It is where the leader goes to check any lead's current status. Dashboard summarises; this screen is the full, filterable, per-lead reality.

**Layout (top to bottom):**

1. **Pipeline status bar** (the key addition — this is how the leader reads system performance at a glance). A horizontal row of stage chips across the top, one per PETA pipeline stage, each showing its live count and acting as a filter toggle:
   ```
   New 40 · AI called 62 · Answered 88 · Appointment 46 · Showed up 31 · Closed 9 · Lost 36
   ```
   - Counts are live from the backend (real stage distribution across the whole lead book, respecting the active date range).
   - Tapping a stage chip filters the table below to just that stage; "All" clears it. The active chip is visually selected.
   - Each chip is colour-coded to its stage (see §2: new=neutral, AI called/Answered=blue/in-progress, Appointment/Showed up=green, Closed=purple, Lost=red).
   - "Still in follow-up" is not a separate invented status — it is the leads sitting in the in-progress stages (e.g. `AI called` + `Answered` + any nurture/retry sub-state PETA tracks). If PETA models retry/nurture as a flag or sub-state rather than a stage, surface it here as an additional filter chip (e.g. "In nurture 28", "In retry 12") sourced from that real flag. Do not fabricate these buckets — bind them to what PETA actually stores.
   - This bar doubles as the performance read: the leader sees intake (New), how far the AI pushed them (AI called → Answered → Appointment), and where they fall out (Lost), all in one line.

2. **Secondary filters + search:** quick filters for Hot (score ≥ threshold), by project, by assigned agent, by source campaign (bind thresholds/stages to PETA). Search by name/phone. These compose with the stage chip selected above.

3. **Lead table** — one row per lead, the per-lead status view:
   - Columns: lead (name + phone), **current stage** (as a coloured status tag), score (colour dot + number), project, intent, budget, assigned agent, last activity (relative time), and a "next step" hint where available (e.g. "appt tomorrow 3PM", "AI retry queued 6PM", "awaiting reply"). The next-step hint comes from the lead's real scheduled action in PETA, not a guess.
   - Row → Lead detail (full history).
   - Sortable by score, last activity, stage. Hide project/intent/budget on mobile; keep name, stage tag, and score.
   - Empty/loading states handled; if a filter yields nothing, say so plainly.

**Data:** Lead list with stage, score, qualification, assigned agent, last-activity timestamp, and each lead's next-scheduled-action — all from PETA. Stage counts from a real aggregate query (grouped count by stage) so the status bar reflects the whole book, not just the current page. Realtime/polling so counts and statuses stay current.

**Lead detail purpose:** Everything the leader needs to decide "who closes this, and is it on track?"
- **Header card:** avatar, name, hot-lead tag if applicable, phone, stage + project + source tags, actions (open WhatsApp thread, assign agent).
- **AI-captured qualification card:** intent, budget, timeline, score — each labelled as captured by the AI from call+chat — plus a short AI summary paragraph and a recommended-agent hint. *This data comes from the Retell post-call analysis + WhatsApp; do not recompute it in the client.*
- **Activity timeline:** chronological events (WhatsApp inbound from which ad, AI pre-call notice sent, Retell call with duration + outcome, appointment set, assignment). Each event from the real records.
- **Right rail:** next appointment card (date/time, consultant, reminder status, no-show-recall status) + call recording player with transcript (streamed from the CallRecord).

**Data:** Lead, its CallRecords, its MessageThread, its appointment, assigned Agent.

### 5.4 WhatsApp review  (WhatsApp-Web-style, supervisory)
**Purpose:** Let the leader **watch** the AI handle WhatsApp conversations and step in when needed. Read-first, with takeover.

**Layout:** two-pane master–detail (thread list | conversation), exactly like WhatsApp Web.
- **Thread list:** per lead — avatar, name, last message preview, time, unread badge, stage tag. Selecting opens the thread.
- **Conversation pane:** header (lead, stage, an "AI handling" indicator). Message bubbles: inbound left (neutral), AI-outbound right (brand blue) **clearly labelled as AI (e.g. "AI (Aisha)") in purple**, human-outbound right (distinct). Show delivery/pending state; mark an AI reply that is awaiting the lead's response.
- **Supervision bar** (bottom): a persistent "you're reviewing — AI is replying automatically" indicator with **Take over** (pauses AI auto-reply so the leader can type) and **Flag for agent** actions. When taken over, show a composer and a "hand back to AI" control.

**Mobile:** list first; tap → conversation with back button.

**Data:** MessageThread + Message (with author type), lead stage. Writes: pause/resume AI on thread, send human message, flag.

### 5.5 AI calling
**Purpose:** Show the Retell outbound operation — how many calls, connect rate, outcomes — and let the leader inspect any call's recording, transcript, and AI analysis.

**Layout:**
1. **Stat row:** calls today · connect rate (live pickups) · appointments from calls · avg call time.
2. **Two-column master–detail:**
   - **Call log** (left) — reverse-chronological list: lead, duration, outcome tag (appointment / callback set / no-appointment / no-answer / refused), time. A "live now" pill with count of in-progress calls. Selecting a call opens detail.
   - **Call detail** (right) — recording player with waveform + progress; analysis chips (sentiment, outcome, intent, budget); an **AI post-call analysis** paragraph; full **transcript** turn-by-turn (AI vs lead, styled distinctly).

**Mobile:** log first; tap → detail.

**Data:** CallRecord list + single-record detail (recording URL, transcript, structured analysis). Realtime for live calls where available.

### 5.6 Campaigns  (Meta Ads integration)
**Purpose:** See ad spend and how it converts down to appointments; manage campaigns to the extent PETA/Meta allows.

**Layout:**
1. **Connection status** — "Meta connected" indicator + last-sync time. "New campaign" action if supported (else deep-link to Meta).
2. **Stat row:** total ad spend · leads generated (+ avg CPL) · cost per appointment · Meta→showroom conversion %.
3. **Active campaigns table:** campaign (name + project), status (active/paused), spend, leads, CPL, appointments, ROAS, row actions (pause/resume if supported).
4. **Spend vs appointments** mini chart (last 7 days) + a card introducing the **Conversions API feedback loop** (push showroom/closing events back to Meta so it optimises for buyers, not clickers) — mark clearly as a later capability if not yet wired.

**Data:** Campaign records from the Meta integration PETA already has. Respect what PETA can/can't control; disable unsupported actions rather than faking them.

### 5.7 Automation  (workflow + script + knowledge base)  — n8n-style
**Purpose:** Let the leader adjust *how* the AI works — edit what it says, what it knows, and its parameters — without touching code. **This release: fixed node structure, editable node content.** (No adding/removing/reconnecting nodes yet — that is a later release.)

**Layout:**
- **Canvas:** a read-only visual flowchart of the automation on a subtle dotted grid, laid out to match the real automation running in PETA. Nodes are typed and colour-coded:
  - Trigger (WhatsApp inbound from Meta CTWA)
  - Action — WhatsApp (pre-call notice; info + slot picker; nurture; confirm+remind) — blue
  - Action — AI call (Retell) — purple
  - Decision (answered? / appointment set?) — neutral, diamond-styled
  - Success (confirm + remind) — green
  Connectors show the flow with Yes/No branch labels. **The node graph must mirror the actual PETA automation** — read it from the backend/workflow definition, don't invent a flow.
- **Node edit panel** (opens on node click, as a right-side drawer): three tabs —
  1. **Script** — the text the AI says/sends at this step, with support for template variables (e.g. `{{lead_name}}`, `{{project_name}}`, `{{price}}`, `{{downpayment}}`, `{{consultant}}`, `{{slot_time}}`) surfaced as insertable chips. Bind variables to the real set PETA's templating supports.
  2. **Knowledge** — the KnowledgeItems the AI can pull from at this step (project fact sheet, rental projections, payment FAQ), with attach/detach and an active/inactive state.
  3. **Settings** — the node's parameters. Examples by node type: AI-call node → call-within window, calling hours, voice/language, answering-machine handling; nurture node → max touches, split-by rule, on-no-reply behaviour; WhatsApp node → send channel, retry count, service-window handling.
- **Top actions:** live status pill, version history, "test run".
- **Legend** for node colours.

**Data:** Workflow definition + KnowledgeItems from PETA. Writes: update node script / attached knowledge / parameters; save as a new workflow version (versioned, reversible). **Editing must write back to the same workflow the live automation executes** — this is the whole point of the screen. If the backend can't yet accept these edits, make the panel functional but clearly mark save as unavailable and log the gap.

**Depth boundary for this release (do not exceed without asking):** visual flow + node edit panel only. No drag-to-reposition, no adding/deleting nodes, no re-wiring edges. Keep the implementation structured so a future release can turn the static canvas into a full react-flow editor.

### 5.8 Knowledge & script library — where the leader uploads project content
**Purpose:** This is the answer to *"where do I upload the project's Q&A, calling script, and WhatsApp material?"* Every project the team runs (the pilot is **Armani Hallson**) needs three kinds of AI content loaded before the automation can work. This screen (or a clearly-labelled section reachable from Automation) is where that content lives and is uploaded. It feeds the Automation node edit panel's Knowledge and Script tabs — the library is the source, the node panel is where each item gets attached to a step.

> **Note:** Uploading is normally done through the **AI ingestion pipeline (§5.11)** — the leader drops raw documents and the AI classifies, structures, improves, and files them here automatically. This §5.8 library is the structured destination and the place to **manually** view, edit, activate, and attach any artifact after ingestion (or to hand-create one). Read §5.11 for the smart upload flow; read this section for the library and manual editing it produces.

**Content types (bind to PETA's real content model if one exists):**
1. **Knowledge base (Q&A / fact sheets)** — e.g. the *Armani Hallson Q&A* (unit counts, blocks, floors, land size, tenure, layout types, carparks, completion year, maintenance fee, EV chargers). Used by the AI to answer lead questions on call and on WhatsApp. Upload as document(s) (PDF/DOCX), parsed into retrievable Q&A/knowledge entries.
2. **Calling scripts** — e.g. the *Armani Hallson calling script* (structured: hook → location → comparison → income → trust-up → appointment → rejection handling). Drives the Retell AI call. Stored as editable script text with the template variables of §5.7.
3. **WhatsApp sequences / material** — e.g. the *Armani Hallson WhatsApp follow-up* (multi-step: proposal → self-intro → project awards → location → … → appointment), **including images/media** (the pilot doc carries ~20 images). Drives the WhatsApp automation. Stored as an ordered set of message steps with attached media.

**Layout:**
- **Project selector** at top (pilot: Armani Hallson) — content is organised per project, since scripts/knowledge are project-specific. Adding a project scopes a new content set.
- **Three sections/tabs** — Knowledge base · Calling scripts · WhatsApp sequences — each a list of items with: name, type, status (active/draft), last updated, and edit/preview.
- **Upload** in each section: accept PDF and DOCX for knowledge and scripts; for WhatsApp sequences accept the doc **and its embedded media**, or a structured step editor. On upload, parse into the structured form the AI consumes (Q&A entries, script sections, ordered WhatsApp steps with media) — do not just store an opaque file the AI can't read. If PETA already has an ingestion/parsing pipeline for AI knowledge, use it; otherwise implement parsing and note it in `DATA-MAPPING.md`.
- **Preview**: let the leader see the parsed result (the Q&A entries extracted, the script sections, the WhatsApp steps with images) so they can confirm it ingested correctly.
- **Edit**: knowledge entries and script text are editable inline with the same variable chips as §5.7; WhatsApp steps editable as an ordered list with media.
- **Attach-to-workflow**: from an item, or from the Automation node panel, bind the item to the workflow step(s) that should use it.

**Data:** KnowledgeItem + Script + WhatsAppSequence content objects, scoped per project, from PETA. Writes: upload/parse, edit, activate/deactivate, attach to workflow node. **Uploaded content must become what the live Retell + WhatsApp automation actually uses** — the whole point is that the leader can load a new project's material and the AI starts using it. If write-back to the live AI isn't wired yet, make upload/preview functional and mark activation as pending, logging the gap.

**Pilot note for the build:** three real Armani Hallson source files exist (Q&A PDF, calling-script PDF, WhatsApp DOCX with images). Use them to shape the parsing and the preview UI — the Q&A PDF defines the knowledge-entry shape, the script PDF defines the script-section shape, the WhatsApp DOCX defines the ordered-step-with-media shape. (These are shared as reference for structure; the shipped system ingests them through this screen, not as hardcoded fixtures.)

### 5.9 First-property signal & experience-based agent routing
**Purpose:** New requirement. When an appointment is set, the team wants to route the closing to the right agent based on **how far along the lead is in their buying journey** — specifically whether this is their *first property viewing* (still surveying widely) versus a seasoned buyer who has viewed many. First-time / early-stage leads go to **newer agents** as supervised closing practice (training value, lower risk of losing a hot deal); leads who have surveyed a lot go to **experienced agents** to close. Budget and intent factor in too.

**How the signal is captured (both sources, cross-verified):**
1. **AI asks.** The Retell call script and the WhatsApp sequence must include a question capturing buying-journey stage — e.g. "Is this your first property / first-time investment, or have you been viewing a few?" *(The pilot WhatsApp sequence already asks "Is this your first-time investment property?" — formalise this as a captured field, not just a chat line.)* The answer is extracted into a structured field by the post-call / post-chat analysis.
2. **System history cross-checks.** The backend also derives journey stage from the lead's own record — e.g. how many appointments/viewings this contact has had across the system. Where PETA can see prior activity for the contact, use it to corroborate or correct the self-reported answer.
3. **Reconcile:** store both the self-reported value and the system-derived value; if they conflict (lead says "first time" but system shows prior viewings), surface both and prefer the system evidence for routing, flagging the mismatch.

**New structured fields (add to the Lead / post-call analysis model — confirm naming against PETA):**
- `buyingJourneyStage` — enum, e.g. `first_time` (first property / surveying widely) · `some_experience` (viewed a few) · `experienced` (viewed many / seasoned investor).
- `selfReportedFirstProperty` — what the lead told the AI.
- `systemObservedViewings` — count/derivation from the backend's own history.
- These join the existing AI-captured qualification (intent, budget, timeline, score).

**Routing rule (this is the requested logic — make it configurable, not hardcoded):**
Combine buying-journey stage with budget and intent to pick the agent tier:
- **First-time / early-stage lead** → assign to a **newer agent** as a supervised closing (training). Especially when budget is modest and intent is own-stay — lower stakes, good practice.
- **Experienced / surveyed-a-lot lead**, or **high budget / clear investor intent** → assign to an **experienced, high close-rate agent** to close.
- Budget and intent can override: a first-time buyer who is nonetheless a high-budget investor may still warrant an experienced closer — expose these thresholds as editable rules rather than fixing them in code.
Agents therefore need an **experience/seniority attribute** (or the existing close-rate already on the Agent object can proxy for tier). Add a seniority/tier field if PETA doesn't have one.

**Where this surfaces in the UI:**
- **Lead detail (§5.3):** show `buyingJourneyStage` (with both self-reported and system-observed values, and a mismatch flag if they differ) alongside intent/budget/timeline in the AI-captured qualification card, and reflect it in the recommended-agent hint ("first-time buyer → suggest newer agent for supervised close" / "seasoned investor → suggest senior closer").
- **Agent allocation (§5.10):** the auto-assign rule uses `buyingJourneyStage` + budget + intent to route to the right agent tier; the rules are editable here. Manual assignment still shows the journey stage so the leader can decide. Team-load view should indicate each agent's tier/seniority so training assignments are visible.
- **Appointment context:** wherever an appointment is shown (dashboard today's-appointments, lead detail), include the journey-stage tag so the assigning leader sees at a glance whether it's a training-suitable lead or a close-now lead.

**Data:** the new fields above from PETA's lead/analysis model; Agent seniority/tier. Writes: the editable routing rules; assignment respecting them. If the backend doesn't yet capture `buyingJourneyStage`, this becomes a backend dependency — flag it in `DATA-MAPPING.md`; do not fake the value. The AI-asks part is a script/sequence change (§5.8 content), so ensure the pilot's call script and WhatsApp sequence include the question.

### 5.10 Agent allocation
**Purpose:** Route AI-booked appointments to the right closer, and host the routing rules from §5.9.

**Layout:**
- **Auto/manual toggle.** Auto-assign on: the rule engine of §5.9 (buying-journey stage + budget + intent → agent tier) routes each appointment; a summary line explains the current rule. Manual: the leader assigns from the unassigned queue.
- **Unassigned queue** — appointments/leads awaiting an agent, each showing name, journey-stage tag, intent, budget, score, so the leader can judge training-suitable vs close-now at a glance.
- **Team load** — each agent with avatar, **tier/seniority** (or close-rate as a proxy), active-lead count, and a load bar. This makes it visible that first-time leads are going to newer agents for practice and hot/experienced-buyer leads to senior closers.
- **Routing rules editor** — the §5.9 thresholds exposed as editable rules (which journey-stage/budget/intent combinations map to which agent tier), not hardcoded.
- Assign / reassign writes back to PETA.

**Data:** Agent (with tier/seniority), unassigned appointments with journey stage + qualification, routing rules. Writes: assign/reassign, edit routing rules.

### 5.11 AI document ingestion — upload once, auto-integrate everywhere
**Purpose:** The headline capability. The leader drops in a project's raw documents and an **AI ingestion pipeline** classifies each one, understands what it is, and automatically wires it into the right part of the system — no manual sorting, no manual workflow drawing, no manual prompt editing. This is the "smart" layer on top of the Content library (§5.8): §5.8 is the structured destination and manual editor; §5.11 is the AI that fills it from raw files.

The pilot is three real Armani Hallson files, and the pipeline must handle exactly this kind of mixed drop:
- a **WhatsApp flow** doc (steps + messages + ~20 images) → AI auto-designs the WhatsApp workflow sequence, preserving message text and placing each image with its step;
- an **AI caller script** doc (hook → location → income → appointment → rejection handling) → AI reviews it, improves it, and integrates it into the Retell caller prompt + attaches it as caller knowledge;
- a **FAQ / Q&A** doc (project facts) → AI turns it into a knowledge base the AI can draw on anywhere (call, WhatsApp, answering ad-hoc lead questions).

**The flow (what the pipeline does):**

1. **Upload (batch).** The leader uploads one or many documents at once (PDF, DOCX incl. embedded images), scoped to a project (pilot: Armani Hallson). No need to say what each file is.

2. **Classify.** For each document, the AI determines its type — WhatsApp sequence / calling script / FAQ-knowledge / other — from its content and structure (don't rely on filename). Show the detected type back to the leader for each file with a confidence signal, and let them correct a misclassification before it commits.

3. **Extract & structure** per type:
   - **WhatsApp sequence →** parse the ordered steps, the message copy under each step, and the images; attach each image to the step/message it belongs with; produce a structured multi-step WhatsApp sequence (the §5.8 WhatsAppSequence shape) ready to run.
   - **Calling script →** parse the script into its sections (hook, location, comparison, income, trust-up, appointment, rejection handling); **the AI reviews and improves it** (clarity, flow, objection handling, compliance-safe phrasing) and produces (a) an updated caller script and (b) the caller-prompt/knowledge integration for Retell. Improvements must be shown as suggestions the leader can accept/reject — never silently rewrite their script.
   - **FAQ / Q&A →** parse into discrete question→answer knowledge entries, normalised and de-duplicated, tagged by topic (units, tenure, layouts, carpark, completion, fees, etc.), available system-wide (call, WhatsApp, ad-hoc answering).
   - **Other / unrecognised →** hold for the leader to classify manually rather than guessing.

4. **Auto-integrate (with a human confirm gate).** The pipeline proposes where each artifact plugs in:
   - WhatsApp sequence → into the WhatsApp automation / the relevant Automation workflow steps (§5.7);
   - Calling script + knowledge → into the Retell caller prompt + caller knowledge;
   - FAQ knowledge → into the shared knowledge base used everywhere.
   Present this as a **review-and-confirm** screen (an "ingestion plan": here's what I found, here's what I'll do with each). The leader approves (or edits) before anything goes live. This gate matters because these artifacts drive the live AI that talks to real customers — auto-integration must not mean unreviewed changes to production behaviour.

5. **Activate.** On approval, write the structured artifacts into the Content library (§5.8) and bind them so the **live Retell + WhatsApp automation actually uses them**. Version each change so it's reversible.

**UI:**
- A drop zone that accepts multiple files, then a per-file processing view (classifying → extracting → structuring → ready), streaming progress.
- An **ingestion plan / review screen**: one card per document showing detected type (editable), the structured preview (WhatsApp steps with images, script sections with the AI's suggested improvements diffed against the original, FAQ entries), and the proposed integration target. Accept / edit / reject per item.
- On confirm, a summary of what was created/updated and links into the Content library, Automation, and caller settings where each landed.

**Data / integration:** This pipeline is AI-heavy — it uses the same model/service PETA already uses for its AI features (reuse, don't introduce a parallel stack). It reads raw uploads, writes structured KnowledgeItem / Script / WhatsAppSequence objects (§5.8), and updates the Retell caller prompt + workflow bindings. **Everything it produces must be reviewable before it goes live, versioned, and reversible.** If any write-to-live target isn't exposed by the backend yet (e.g. programmatic update of the Retell prompt, or of the WhatsApp automation), the pipeline still classifies, extracts, improves, and previews — and marks the final activation as pending, logging the gap in `DATA-MAPPING.md`. Never silently push unreviewed content to the live AI, and never fake a successful integration.

**Relationship to §5.8:** §5.11 is the front door (AI ingestion). §5.8 is the library the ingestion writes into and where the leader can later hand-edit any artifact. Both exist: the AI does the heavy lifting on upload; the human retains full manual control afterward.

**Boundary for this release:** the pipeline classifies the three known types (WhatsApp sequence, calling script, FAQ-knowledge) well; "other" types are held for manual handling rather than force-fit. The auto-integration always passes through the human confirm gate — no fully-silent production changes in this release.

### 5.12 Settings (Owner/Admin) — connections, team, billing
**Purpose:** The tenant admin surface. Where a tenant connects its own WhatsApp + Meta accounts, manages who's on the team, and handles subscription. Owner/Admin only; a Leader or Agent must not reach it.

**Connections** (the important one — see §4A):
- Two connection cards: **WhatsApp Business** and **Meta Ads**. Each shows status (connected / not connected / needs re-auth), the bound identity (WhatsApp number / Meta ad-account + page), health + last-sync, and connect / reconnect / disconnect actions.
- **Self-serve connect flow** using PETA's existing mechanism (OAuth via Meta Login / WhatsApp embedded signup where available, else guided credential entry that matches how PETA stores these). Never show raw secrets.
- These connections are what the whole product runs on — until connected, dependent screens show a "connect to begin" empty state.

**Team & roles:**
- List tenant users with role (Owner/Admin · Leader · Agent), invite by email, assign/change role, deactivate.
- In a solo tenant this can be minimal (just the one user) but the screen still exists for when they grow.

**Billing / subscription:**
- Plan, usage, and billing entry. If PETA/existing billing handles this, deep-link or embed it rather than rebuilding. Mark as pending if not yet exposed.

**Data:** Tenant, Users + roles, Connections — all bound to PETA. Writes: connect/disconnect WhatsApp + Meta, invite/role changes, billing actions. Anything not yet exposed by the backend → functional UI with the action marked pending, logged in `DATA-MAPPING.md`. Never fake a connected state or a successful invite.

---

## 6. The two "money" numbers — handle with care

Two figures anchor the sales value but are easy to fabricate. Both must be **defensible or clearly labelled as projections with the formula visible** — never presented as authoritative magic numbers.

### Commission saved (Dashboard hero)
Represents the appointment-cut (20%) the AI replaced. Before displaying it:
- Derive it from a transparent formula the leader can see on hover/expand — e.g. appointments the AI set × the leader's configured appointment-commission value, or a leader-entered assumption. Read the commission model from PETA if it stores one.
- If it can only be an assumption, **label it "projected" and expose the inputs.** Do not present an assumption as measured fact.

### Coverage / "no leakage" (Coverage screen + Dashboard band)
- **Only** the log-derived coverage metrics of §5.2. **No baseline, no "would have leaked", no recovery count** — the customer has no historical data at launch. Re-read §1's honesty rule. This constraint is not negotiable for this release.

Once a customer has run long enough to have their *own* historical data, a later release may add trend-over-time comparisons against their own past. Not now.

---

## 7. Out of scope for this release
- **Closing-agent view** — the slimmer per-agent app (today's appointments + client objections + navigate-to-showroom). Different surface, later.
- **Full drag-and-drop workflow editor** (add/remove/reconnect nodes) — this release is edit-content-only.
- **Conversions API write-back to Meta** — introduce the card, wire later.
- **Any baseline / recovery analytics** — until customers have their own history.

---

## 8. Acceptance criteria (definition of done)
1. **No mock data in the shipped build.** Every screen renders from the live PETA backend via the typed data-access layer. Any place data can't yet be sourced is listed in `DATA-MAPPING.md` and shown in an explicit empty/disabled state — never faked.
1a. **Multi-tenant & role-correct (§4A).** All data is tenant-scoped server-side; the three roles (Owner/Admin · Leader · Agent) are enforced server-side, not just in the UI; an Agent cannot reach team-wide data; a solo tenant works as a tenant of one. Tenancy + RBAC are bound to PETA's existing mechanism, not reinvented. Cross-tenant data exposure is a release blocker.
1b. **Per-tenant connections (§4A/§5.12).** Each tenant self-connects its own WhatsApp Business + Meta Ads account via PETA's mechanism; all downstream screens key off the tenant's own connection; unconnected tenants see honest "connect to begin" states, never mock or another tenant's data.
1c. **Built in depth, one slice at a time (§10).** `BUILD-PROGRESS.md` exists and is honest; slices were completed in §9 order, each meeting the §10.2 Definition of Done before the next began; no shallow scaffolding of unbuilt screens.
2. `DATA-MAPPING.md` exists and maps every screen to real PETA entities/endpoints, with tenancy and gaps flagged.
3. All navigable pages implemented (Dashboard, Coverage, Leads+detail, WhatsApp review, AI calling, Campaigns, Agent allocation, Automation, Content library, Upload & integrate, Settings), reachable via role-aware sidebar.
4. **Both desktop and mobile are fully responsive**, including the two master–detail screens and the off-canvas sidebar drawer.
5. Dark mode works across every screen.
6. The **no-leakage / coverage honesty rule (§1, §6) is respected**: no counterfactual or baseline numbers anywhere.
7. AI-authored WhatsApp and call content is visually distinguished from human/lead content.
7a. The **Leads screen has the pipeline status bar** (live per-stage counts, click-to-filter) and each table row shows the lead's current stage as a status tag plus its next scheduled step — so the leader can read overall AI performance and check any individual lead's status without leaving the page. Stage counts come from a real aggregate query over the whole book. The three-screen role split (Dashboard = summary/queue, Leads = per-lead status source of truth, Coverage = no-leakage proof) is respected with no duplication.
7b. **Content library (§5.8)** lets the leader upload per-project knowledge (Q&A/fact-sheets), calling scripts, and WhatsApp sequences (with media), parse them into the structured form the AI consumes, preview the parsed result, and attach items to workflow steps. Uploaded content becomes what the live Retell + WhatsApp automation uses (or activation is marked pending with the gap logged).
7d. **AI document ingestion (§5.11)** implemented: the leader can batch-upload raw documents; the AI classifies each (WhatsApp sequence / calling script / FAQ-knowledge / other) with a correctable confidence signal; extracts and structures each type (WhatsApp steps + images placed per step; calling script parsed, **AI-improved as accept/reject suggestions**, integrated into the caller prompt + knowledge; FAQ into system-wide knowledge entries); presents a **review-and-confirm ingestion plan**; and on approval writes versioned, reversible artifacts into the library and binds them so the **live** Retell + WhatsApp automation uses them. No unreviewed content ever reaches the live AI; activation gaps are logged in `DATA-MAPPING.md`, never faked.
7c. **First-property signal & routing (§5.9/§5.10)** implemented: `buyingJourneyStage` (self-reported + system-observed, with mismatch flag) shows in Lead detail and appointment context; agent allocation routes first-time/early-stage leads to newer agents and experienced/high-value leads to senior closers via **editable** rules combining journey stage + budget + intent; agents carry a tier/seniority. If the backend doesn't yet capture the signal, it's flagged in `DATA-MAPPING.md`, not faked.
8. The Automation node edit panel reads and writes the **same** workflow the live automation runs (or clearly marks save as unavailable with the gap logged); node structure is fixed this release.
9. Brand applied: ink `#0E1B33`, blue `#1E6FE0` (dark-mode `#4D9BFF`), logo mark present.
10. Quality floor: visible keyboard focus, `prefers-reduced-motion` respected, tap targets ≥40px, no console errors on any screen.

---

## 9. Suggested build sequence
1. Read PETA backend (incl. its tenancy/RBAC and WhatsApp/Meta integration); write `DATA-MAPPING.md`.
2. **Tenancy + auth foundation first:** session → current tenant, role gating (Owner/Leader/Agent), tenant-scoped data-access layer. Everything else is built on this. (§4A)
3. App shell: sidebar, top bar, routing, theming (light+dark), responsive drawer, role-aware nav.
4. Data-access layer bound to PETA, tenant-scoped by construction.
5. Settings → Connections (§5.12) — a tenant must connect WhatsApp + Meta before most screens have data; build this early so the rest has something real to read.
6. Dashboard → Coverage (get the framing + money-number handling right early).
7. Leads list → Lead detail.
8. AI calling.
9. WhatsApp review.
10. Campaigns.
11. Agent allocation (incl. §5.9 first-property routing rules).
12. Automation (canvas + node edit panel).
13. Content library (§5.8 upload/parse/preview/attach) — pairs with Automation.
14. AI document ingestion (§5.11 classify → extract → improve → review → activate) — builds on the library and the caller/WhatsApp bindings.
15. Pass over responsive, dark mode, empty/disabled states, tenant-isolation review, acceptance checklist.

---

## 10. Ways of working — MANDATORY (read before writing any code)

This section governs *how* you build, and it is not optional. The failure mode to avoid is **scaffolding every screen shallowly so it looks finished while nothing actually works end-to-end.** Do the opposite: build **one slice at a time, to real depth, wired to real data, verified, before starting the next.** A half-built product with three solid, real screens is worth more than twelve fake ones.

### 10.1 Build one slice at a time, depth-first
- Follow the build sequence in §9 **in order**. Do **not** create placeholder versions of all pages up front.
- A "slice" = one page (or one tight page pair like Leads → Lead detail) taken to **done** per the definition below, wired to the real PETA backend, before you move on.
- Do not start slice N+1 until slice N meets its Definition of Done and you have reported it (see 10.3).

### 10.2 Definition of Done for a single slice
A slice is done only when **all** of these hold — not before:
1. **Real data.** It reads/writes the live PETA backend through the tenant-scoped data-access layer. No mock objects, no hardcoded rows, no `TODO: fetch later` standing in for data. If a needed endpoint doesn't exist, the slice shows a real empty/disabled state and the gap is in `DATA-MAPPING.md` — that is the *only* acceptable substitute for real data.
2. **Tenant + role correct.** Data is tenant-scoped; role gating enforced server-side; an Agent can't reach team data on this slice.
3. **States handled.** Loading, empty, error, and not-yet-connected states all exist and look intentional — not a blank screen or a spinner that never resolves.
4. **Responsive.** Works at desktop and mobile widths, including any master–detail behaviour.
5. **Dark mode.** Correct in both themes.
6. **No console errors** on the slice; no dead buttons (every control either works or is explicitly, visibly disabled with a reason).
7. **Honesty rules respected** (§1/§6): nothing fabricated, no baseline/counterfactual numbers, AI-authored content visually marked.
8. **Matches its §5 spec** for layout, data, and interactions.

### 10.3 Report after every slice, then continue
After finishing each slice, post a short progress note and **pause for a beat** rather than silently barrelling on:
- what slice was completed,
- which PETA endpoints/entities it was wired to,
- any gaps written to `DATA-MAPPING.md`,
- what the next slice is.
This gives the human a natural checkpoint to catch drift early. Keep these notes terse.

### 10.4 Quality bar — no shortcuts that fake completeness
- **Never fake success.** No mock data in shipped code, no hardcoded "connected" states, no buttons that pretend to save. If it isn't wired, it's visibly pending. (This repeats across the spec because it is the number-one thing to get right.)
- **Reuse PETA, don't reinvent.** Tenancy, RBAC, WhatsApp/Meta connections, the AI model/service — bind to what PETA already has. Building a parallel version is a defect, not initiative.
- **Small, reviewable commits per slice**, with a message naming the slice. Don't land the whole app in one giant change.
- **Don't silently expand scope.** The §7 out-of-scope items and the depth boundaries (Automation = edit-content-only §5.7; ingestion always human-gated §5.11) are limits. If something seems to need crossing a boundary, ask — don't just do it.
- **When unsure, ask rather than guess.** A wrong assumption baked across screens is expensive; a question is cheap.

### 10.5 Track progress in a checklist file
Maintain a `BUILD-PROGRESS.md` in the repo that lists every slice from §9 with its status (not started / in progress / done) and its Definition-of-Done checkboxes (10.2). Update it as you go. This is the artifact the human uses to verify you're building in depth, one by one, and not skipping the hard parts. Keep it honest — a slice is "done" only when 10.2 genuinely holds.

### 10.6 How the human will verify quality (so build to survive this)
The human will spot-check by: opening a "done" slice and confirming it shows *their real tenant's* data (not mock); switching to an Agent account and confirming team data is unreachable; disconnecting a WhatsApp/Meta account and confirming dependent screens degrade honestly; resizing to mobile; toggling dark mode; and clicking every control to find dead/faked ones. A slice that would fail this spot-check is not done, regardless of how it looks.

---

*End of specification. If anything here conflicts with the existing PETA backend contract, follow the backend and note the deviation in `DATA-MAPPING.md`. Build in depth, one slice at a time, per §10.*
