Skip to main content

WiseAI Realtor — Analytics & Reporting Expected Output Spec

⛔ STATUS: DRAFT — NOT APPROVED. CLAUDE.md Rule #17 (HARD GATE) is NOT satisfied.

Stage-1 agent research, pre-populated from the realtor design docs + the analytics.html mock. Do not build the customer-facing screen until the founder approves and confirms the open items in a Stage-2 interview.

Sourced from (read-only, 2026-06-29): backend-completeness-audit.md (the five "which X creates leads" reports = the core value narrative; speed-to-lead; first-vs-last touch), data-model.md §4 (the lead-source taxonomy + first/last touch on re_contacts; re_interactions as the attribution stream), compliance-privacy-analytics.md (first-party / privacy-safe attribution), design-direction.md (KPI tile, color rules), and realtor-mockups/analytics.html.


0. Scope — what this spec covers, and what it does NOT

This spec covers the Analytics & Reporting workspace — the value-narrative reporting: a KPI strip, lead-source attribution & ROI (first vs last touch), a conversion funnel with drop-off, speed-to-lead + unactioned, a language breakdown, the "what's creating your leads" panels (top listings / QR signs / content), and team performance — plus date range, compare, export, and scheduled reports.

Does NOT cover: the QR builder + its own scan analytics (realtor-qr-campaigns-mvp.md — QR appears here as one source); the dashboard's "Today" tiles (realtor-dashboard-mvp.md — analytics is the deeper "Insights" view); the deals board (realtor-deals-mvp.md); raw event capture (voice/chat → re_interactions, ai-front-desk.md).

Build posture: Partial → new (information-architecture.md build map — demo-event analytics exist; the realtor-framed reporting view is new). Reads the proposed re_interactions/re_contacts spine + existing lead_events (migrate-before-use).


1. The mock screen this spec governs + what it reads

Governs: realtor-mockups/analytics.html — section tabs (Overview / Attribution & ROI / Funnel / Team), a date-range + Compare: prev. period toggle, Export + Schedule report, and a "First-party · privacy-safe · no cookie banner needed" note. Sections:

  • KPI strip (5): Leads, Lead→client %, Showings booked [§6], Deals firm/closed, GCI pipeline (weighted) [§3 — deferred/capability-gated].
  • Lead-source attribution & ROI: a table (Source, Leads, Share, Cost/lead, Deals, GCI [§3]) with a First touch ⇄ Last touch toggle + an "Aria's read" insight.
  • Leads by language (auto-detected) + a Punjabi-conversion insight.
  • Conversion funnel: Visits/scans → Chat/voice → Lead → Appointment → Client → Closed, with drop-off % per step (biggest drop highlighted).
  • Speed-to-lead: median first response (AI < 1m vs human follow-up), a response-time distribution, and an unactioned > 24h alert list.
  • What's creating your leads: Top listings / Top QR signs (scans→leads) / Top content by leads.
  • Team performance: Terry vs Sheri (+ Aria as the AI front office row: median response < 1m, "books & qualifies before hand-off") with GCI columns [§3].

Reads (target-state — WS7; verify exact route names; do not fabricate):

ReportUnderlying read
KPI stripre_contacts (leads, lead→client), re_deals (firm/closed, value), showings (captured requests §6)
Source attribution & ROIre_contacts.source_category/source_detail + first_touch_*/last_touch_* (the toggle); cost where ad spend is connected
Funnelre_interactions (visit/scan → chat/voice) → re_contacts (lead → appointment → client) → re_deals (closed)
Speed-to-leadre_interactions (first inbound vs first outbound), unactioned threshold
Language breakdownre_contacts.preferred_language (auto-detected)
What's creating leadsre_interactions grouped by listing / QR campaign / content piece
Team performanceper-agent rollups (local_business_agents ownership)
GCI / commissionDEFERRED (A2) + capability-gated (rbac.ts) — see §3

Demo tenant: Terry & Sheri Real Estate (…0c01). Mock data is demo; NEVER a real customer (feedback_never_modify_customer_data).


2. The AI-Bridge / honesty anchor

  • Honest, first-party attribution only. Every number is a real count from the event stream — no fabricated figures, no "opens/impressions" dressed up as engagement (honest metrics: scans/clicks/leads/deals, real bounce — never "Delivered/Opened" theater). A no-data range reads honestly ("Not measured / no data this period"), not a placeholder chart.
  • "Aria's read" is an insight, not advice. The AI-summary callouts (e.g. "shift spend from Google Ads to QR") are framed as a suggestion to the agent, grounded in the shown numbers — never a guarantee, a valuation, or financial advice (ai-guardrails.md RULE 2).
  • Privacy-safe. First-party attribution (no third-party cookie banner needed) per compliance-privacy-analytics.md; PIPEDA/Law 25 honored.

3. GCI / commission in analytics — DEFERRED (A2) + capability-gated (rbac.ts)

⚠️ NEW INCONSISTENCY — flagged, not silently resolved. The analytics.html mock shows a GCI pipeline ($186k) hero KPI, GCI columns in the source table, and per-agent GCI ($102k / $84k) in Team performance. But A2 = commissions deferred and this batch's directive says commission is role-gated and deferred. Reconcile (consistent with realtor-deals-mvp.md §3):

  • MVP: analytics ships without GCI/commission. The hero KPI uses volume ($ transaction volume) or deal count — not GCI; the source table and team table omit the GCI column (or show volume). This avoids depending on deferred commission data.
  • If/when commission lands (post-MVP, founder-gated): GCI/commission is gated by capability (rbac.ts): brokerage_owner edits; broker_admin/team_admin/ brokerage_owner read at brokerage/team scope; an agent reads their OWN commission (commissions:amount:read:own) — so an agent's own-performance GCI is visible to them, but team/peer GCI is not; isa/transaction_coordinator/ marketing_assistant/external_partner have no commission capability; enforced at the API/query layer; every read logged (data-model.md §5.2).
  • Stage-2 confirms: defer GCI in analytics entirely for MVP (recommended), or ship it capability-gated.

Other role scoping:

BucketRoles (rbac.ts)Analytics scope
Brokerage managementbrokerage_owner, broker_admin (brokerage scope)Brokerage-wide reports + Team performance (per-agent comparison); GCI (read brokerage) if it lands
Team managementteam_admin (team scope)Team reports + team performance; GCI (read team) if it lands
Agent / ISAagent, isa (own scope)Own performance + own-attributed sources/funnel; no peer comparison; an agent sees own GCI (read:own) if it lands, isa none
Support / externaltransaction_coordinator, marketing_assistant, external_partner (bounded)Scoped/read-only; never commission capability

4. Expected outputs — the five "which X creates leads" reports

4.1 — Lead-source attribution & ROI (first vs last touch)

Should see:

  • A ranked source table (QR yard signs / Website-AI chat / REALTOR.ca / Google Ads / Referral…) with Leads, Share, Cost/lead, Deals, and a First touch ⇄ Last touch toggle that recomputes attribution (from re_contacts.first_touch_* vs last_touch_* + the re_interactions multi-touch history, data-model.md §4). AI-owned sources honestly at $0/lead; paid sources at real cost where spend is connected (else cost "—").
  • An honest blended cost + total row.

Should NOT see:

  • Fabricated cost where no spend is wired (show "—").
  • GCI column in MVP (§3).

Success: the agent sees which sources produce leads and deals, at what cost, under both first- and last-touch attribution.


4.2 — Conversion funnel with drop-off

Should see:

  • A funnel: Visits/scans → Chat/voice → Lead captured → Appointment → Client → Closed, each step with a count and the drop-off % to the next, with the biggest drop-off highlighted + a plain-language note ("nurture longer").
  • End-to-end summary (e.g. "2,140 visits → 6 closings (0.28%)").

Should NOT see:

  • A funnel step that double-counts or shows an impossible (>100%) conversion.
  • "Appointment" implying the AI booked it (§6 — captured request → agent confirm).

Success: the agent sees where prospects fall out of the funnel and where to focus.


4.3 — Speed-to-lead + unactioned

Should see:

  • Median first response (AI < 1m, all hours) vs median human follow-up, a response-time distribution, and an unactioned > 24h alert list (the speed-to-lead enforcement, tied to Notifications realtor-notifications-mvp.md).

Should NOT see:

  • A speed-to-lead number that ignores the human leg (show both AI + human).

Success: speed-to-lead is measured honestly (AI instant, human follow-up separately) and stale leads are surfaced.


4.4 — Language breakdown + "what's creating your leads"

Should see:

  • Leads by language (auto-detected preferred_language) with an insight (the Punjabi-conversion wedge) — languages shown are whatever the data contains, not a hardcoded list.
  • What's creating leads: Top listings by leads, Top QR signs (scans→leads), Top content by leads — the concrete "which X creates leads" answers.

Should NOT see:

  • A hardcoded language set; fabricated content/listing/QR numbers.

Success: the agent sees which listings, signs, content, and languages actually produce leads.


4.5 — Team performance + date range / compare / export / scheduled reports

Should see:

  • Team performance (brokerage/team management): per-agent Leads / median response / appointments / deals / lead→client, with Aria shown as the AI front-office row (instant response, "books & qualifies before hand-off" → captures & qualifies, §6). GCI columns deferred/capability-gated (§3).
  • A date range + Compare: prev. period, Export, and Schedule report (a scheduled report is a delivery to the account's own users — a staff alert, not a prospect send — and is allowed; it must NOT email a lead/client).

Should NOT see:

  • An agent-scope user seeing the per-agent comparison or another agent's numbers (§3).
  • A "scheduled report" that sends to a prospect (it goes to the account's own users only — boundary in realtor-notifications-mvp.md §1).

Success: management compares team performance and schedules reports to itself; agents see only their own.


5. Empty / loading / error states

StateExpected output
No data in rangeHonest "No data for this period" per report — never a fabricated chart (anti-pattern #6 / honest metrics).
Source unconnected (e.g. ad spend)Cost reads "—"; leads still shown; no invented cost.
LoadingPer-section skeletons, not a spinner (anti-pattern #7).
Read errorInline "Couldn't load this report — retry"; other sections still render.
Export/schedule errorInline retry; nothing partially sent.

6. Carried-forward constraints (consistent across the batch)

  • Aria does NOT book/schedule — "Showings booked" KPI / funnel "Appointment" / team "books & qualifies" all reflect captured showing requests (agent- confirmed), never AI-confirmed bookings (ai-front-desk.md decision 4; relabel e.g. "Showing requests" / "captures & qualifies").
  • GCI/commission deferred (A2) + capability-gated (§3).
  • SMS off-by-default + consent-gated; crisis never gated (a scheduled report is a staff alert, never a prospect send — realtor-notifications-mvp.md §1).
  • Role enum (rbac.ts — implemented source of truth): agent | team_admin | transaction_coordinator | broker_admin | brokerage_owner | marketing_assistant | isa | external_partner (scopes own|team|brokerage).
  • No realtor pricing ("$0/lead" is an honest attribution stat, not a price).
  • Honest metrics only (no Delivered/Opened theater); language never hardcoded; first-party / privacy-safe attribution.

7. Accessibility (AODA → WCAG 2.1 AA)

  • Charts (sparklines, funnel, bars, distributions) have text/table equivalents and data labels; meaning never conveyed by color alone.
  • Tables: real header/row semantics; sortable/toggle controls labelled with state; numerals tabular-nums.
  • Section tabs + first/last-touch + compare toggles are keyboard-operable with visible focus.
  • Insights ("Aria's read") are real text, readable by assistive tech.
  • Contrast ≥4.5:1; gold = accent only (e.g. the GCI hero accent — and only if/when GCI ships, capability-gated); teal links/actions meet AA; reduced-motion honored.

8. Acceptance checklist (QA runs on the deployed URL)

Behavioural verification on wiseaiagency.com (real host) against the demo tenant (…0c01); never "build passes". Sample at ≥2 timepoints.

// The five reports + honesty
test.fixme('source attribution table recomputes on First touch ⇄ Last touch; AI sources $0/lead; cost "—" when unwired', () => {});
test.fixme('conversion funnel shows per-step drop-off (biggest highlighted); no >100% / double-count', () => {});
test.fixme('speed-to-lead shows AI median AND human follow-up separately + unactioned>24h list', () => {});
test.fixme('language breakdown is data-driven (not hardcoded); "what creates leads" ranks listings/QR/content from real events', () => {});
test.fixme('no fabricated numbers anywhere; a no-data range reads "No data for this period"', () => {});

// Commission deferred + RBAC
test.fixme('MVP analytics show NO GCI/commission (deferred A2); hero uses volume/deal-count, not GCI', () => {});
test.fixme('if GCI ships, it is capability-gated (brokerage_owner edits; broker_admin/team_admin read at scope; agent reads OWN; isa/support/external none); peer/team GCI never shown to an agent; API-enforced + read-logged', () => {});
test.fixme('an agent sees only own performance — no team comparison, no peer numbers; sees OWN GCI (read:own) if it ships, never peer/team GCI; isa none', () => {});

// Reports delivery + carried-forward
test.fixme('"Schedule report" delivers to the account’s own users only — never to a lead/client', () => {});
test.fixme('"Showings booked"/"Appointment"/"books & qualifies" reflect captured REQUESTS, not AI-"booked"', () => {});

// States + a11y
test.fixme('no-data/unconnected/loading/error/export-error states render per §5; never a fabricated chart', () => {});
test.fixme('charts have text/table equivalents; toggles keyboard-operable; no color-only meaning; reduced-motion honored', () => {});

9. Guardrails for agents building against this spec

  • Rule #17 not satisfied — do not build until founder approval.
  • Honest, first-party attribution only — real counts or "Not measured"; never Delivered/Opened theater; privacy-safe (compliance-privacy-analytics.md).
  • GCI/commission deferred (A2) + capability-gated — MVP ships volume, not GCI; reconcile with realtor-deals-mvp.md §3 + data-model.md §1.4 before building (flag for founder); if it lands, gate + log (data-model.md §5.2).
  • Scheduled reports go to the account's own users, never a prospect (realtor-notifications-mvp.md §1; feedback_never_cron_send_campaigns).
  • Migrate-before-usere_interactions/re_contacts/re_deals are proposals; verify columns via information_schema (Rule #18); founder-gated DDL.
  • Aria books nothing; language never hardcoded; honest metrics; verify on the real host; behaviour not DOM presence; evidence-or-nothing.
  • If code diverges, update the spec first (founder approval), then the code.

End of spec. STATUS: DRAFT — NOT APPROVED. Open items for Stage-2: (1) defer GCI in analytics entirely for MVP vs capability-gated (reconcile mock vs A2); (2) the attribution model default (first vs last touch) + whether multi-touch weighting is in MVP; (3) which reports are exportable/schedulable; (4) ad-spend connection sources for real cost/lead.