WiseAI Realtor — Website Builder 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 four website mocks. Do not build the customer-facing screens until the founder approves and confirms the open items in a Stage-2 interview.
Sourced from (read-only, 2026-06-29):
do-not-reinvent.md(the shippedWebsiteEditordraft/publish +draft_*columns +RealEstateSiteTemplate+ the/s/[slug]/*sub-pages + 14 guides + the listings direction),compliance-privacy-analytics.md
backend-completeness-audit.md(the brokerage-identity invariant, MLS®/DDF, consent/PIPEDA/Law 25, AODA, Canadian hosting),design-direction.md(Settings/ big-box module grid; focus-mode editor), andrealtor-mockups/{website-pages, website-editor, website-tracking-compliance, template-picker}.html.
0. Scope — what this spec covers, and what it does NOT
This spec covers the Website pillar inside the one backend (decided 2026-06-27 — Website is a nav pillar, not a separate app): the Pages manager, the launched focus-mode visual editor, the Area-Guide editor, the Template picker + brand kit, and Tracking & Compliance (the publish gate).
Does NOT cover (cross-referenced, not duplicated):
- The public rendered site (
/s/[slug]/*,RealEstateSiteTemplate) — already shipped (do-not-reinvent.md); this spec governs the builder/admin of it. - The shipped content editor / blog behaviour —
acceptance/real-estate-content-editor-mvp.mdreal-estate-blog-mvp.md(approved); the Pages "Edit → focus editor" reuses the existingWebsiteEditor.
- Listings management (
realtor-listings-mvp.md); Reviews page content (realtor-reviews-manager-mvp.md); the cross-property Pro Website system (acceptance/cwa-pro-website.md,pro-website-multipage.md).
Build posture: the WebsiteEditor (draft/publish, target=website_draft,
draft_* columns), the editor API (api/real-estate/site-content), the template,
and the 14 guides already shipped (do-not-reinvent.md). This spec extends
them with the in-dashboard Pages manager + Tracking & Compliance gate — do not
rebuild the editor.
1. The mock screens this spec governs + what they read
Governs website-pages.html: the Pages library under a Website sub-nav
(Templates / Pages / Brand kit / Domain / Tracking & Compliance). Rows mirror the
real /s/[slug] sub-pages: Home, Featured (Scroll carousel), Listings & Search
(DDF), Area Guides hub + nested guides (Woodstock/Ingersoll/Tillsonburg + a
Norwich draft with a "No meta" SEO warning), About, Reviews, Tools, Blog,
Partners (draft), Contact (AI front desk) — plus Utility/system pages (Privacy
PIPEDA·Law25, Terms & DDF disclaimer, Accessibility AODA, Yard-Sign QR landing).
Each row: status (Published/Draft), per-language (EN/FR/ਪੰ), SEO/GEO (Good / a
"No meta" warning), drag-to-reorder, Edit → focus editor. A brokerage-identity
hint banner up top.
Governs website-editor.html: the launched full-screen focus-mode visual
editor (exits to dashboard; drives the existing WebsiteEditor draft/publish).
3-pane: blocks library · live Team Beckett canvas (section selected) · properties
- Aria AI assist with a fair-housing guard. Device toggle, autosave, Draft →
Publish. Surfaces the DDF read-only-but-feature/reorder rule (
realtor-listings-mvp.md§4.2).
Governs template-picker.html: in-dashboard chooser — 6 template families
(Local Authority, Luxury, Signature Agent, Modern Team, Multilingual Community,
Brokerage Pro) + brand kit (logo, colours, fonts, button/card style) → launches
the focus editor.
Governs website-tracking-compliance.html: the publish-GATING compliance
dashboard — a readiness summary (province RECO/TRESA · "Clear to publish"), and
sections: Brokerage identity (required-to-publish, live footer preview),
Trademark & DDF ("Powered by REALTOR.ca" ≥90px, MLS®/REALTOR® rules, "courtesy
of", off-market auto-expire), Analytics (first-party built-in; GA4 after
consent; Resend click-tracking OFF by design; Meta/Ads pixel), Cookie consent
& privacy (PIPEDA/Law 25, categories, QC French/Bill 96 advisory), Accessibility
(AODA · WCAG 2.1 AA), Hosting & domain (Canada region, custom domain, BYO embed).
Reads/writes (verify exact route names; do not fabricate):
| Surface | Underlying store |
|---|---|
| Pages library + status + order | local_businesses.metadata.website {draft,published} (page set) + the /s/[slug] route map |
| Focus editor save | the existing WebsiteEditor → draft_* twin columns via api/real-estate/site-content (target=website_draft) → Publish |
| Area guides | src/lib/real-estate/guides.ts (14 guides) + content overrides |
| Brand kit / template | site-config + brand kit fields |
| Brokerage identity + compliance | brokerage-identity fields (legal name + "Brokerage" + RECO# + office address + registered agents); compliance flags |
| Analytics toggles | first-party (built-in) + GA4 (consent-gated) + Resend click-tracking (OFF by design) |
Demo tenant: Terry & Sheri Real Estate (…0c01, terry-and-sheri); the
mock's terry-and-sheri.john316.church / teambeckett.ca are demo. NEVER a real
customer (feedback_never_modify_customer_data).
2. The AI-Bridge / honesty anchor
- Aria assists editing with a fair-housing guard. The editor's AI assist
generates/rewrites section copy through the same fair-housing + no-advice
guardrails (
ai-guardrails.md); it never writes steering copy or a home-value claim into a page. - Honest compliance state. The compliance dashboard reflects real check results (brokerage identity present/absent, AODA audit, hosting region) — not a cosmetic "all green". A failing required check blocks publish (§4.4).
3. Role-based visibility
| Bucket | Roles | Website scope |
|---|---|---|
| Brokerage management | brokerage_owner, broker_admin (brokerage scope) | Full builder + publish + compliance fields (brokerage identity, domain, hosting) |
| Team management | team_admin (team scope) | Builder + publish for team pages; brokerage-identity fields read-only |
| Agent / ISA | agent, isa (own scope) | Edit assigned pages per policy; cannot change brokerage identity / publish-gating compliance |
| Support / external | marketing_assistant, transaction_coordinator, external_partner (bounded) | marketing_assistant edits content per policy; view/scoped otherwise; no publish of compliance-critical changes; external_partner read-only |
4. Expected outputs
4.1 — Pages manager (library + reorder + status + language + SEO/GEO)
Should see:
- The page library mirroring the live
/s/[slug]sub-pages, grouped In navigation (drag-to-reorder sets the nav menu order) and Utility/system (not in nav). Each row: page name + type chip (Homepage / Scroll carousel / DDF feed / Hub · N guides / Reviews Engine / AI front desk / etc.), status (Published/Draft), per-language chips (EN/FR/ਪੰ — the tenant's languages, not hardcoded), an SEO/GEO indicator (Good / a "No meta" warning), last edited, Edit. - The Area Guides hub expands to nested guides with their own status/ language/SEO + an Add area guide affordance.
- A brokerage-identity hint banner linking to Tracking & Compliance.
Should NOT see:
- A page published with a missing-meta SEO warning silently ignored (it's flagged; the Norwich draft is the example).
- A hardcoded language set per page.
Success: the agent sees every page, reorders the nav by drag, spots SEO gaps, and opens any page into the focus editor.
4.2 — Focus-mode visual editor (extends the shipped WebsiteEditor)
Should see:
- A launched full-screen editor (exits back to the dashboard) — 3-pane: blocks library · live canvas (selected section) · properties + Aria AI assist (with fair-housing guard). Device toggle (desktop/mobile preview), autosave, Draft → Publish.
- It drives the existing
WebsiteEditordraft/publish (target=website_draft →draft_*columns); Publish promotes draft → published. - The DDF read-only-but-feature/reorder rule is surfaced where listings appear
(consistent with
realtor-listings-mvp.md§4.2).
Should NOT see:
- A rebuilt editor that bypasses the shipped draft/publish pipeline.
- A save that 500s on a new section/enum value because only one of the
draft_*/ published CHECK constraints was widened (§9 —feedback_draft_twin_constraints_must_match).
Success: the agent edits a section, autosaves a draft, previews mobile, and publishes — through the existing pipeline.
4.3 — Template picker + brand kit + Area-Guide editor
Should see:
- A Template picker (6 families) + brand kit (logo, colours, fonts, button/card style) that launches the focus editor; switching template/brand kit re-skins without breaking accessibility (contrast preserved).
- An Area-Guide editor over the 14 guides (
guides.ts) — create/edit a neighbourhood guide, per-language, with SEO/GEO meta (the "No meta" warning is the gate to fix before publish).
Should NOT see:
- A brand-kit choice that drops text contrast below AA (the design system fixes this — gold never body text, teal action accent).
Success: the agent picks a template + brand kit and authors area guides that publish cleanly.
4.4 — Tracking & Compliance: the brokerage-identity publish GATE (WS11 hook)
This is the compliance hook the WS11 pass enforces. The brokerage-identity invariant is RECO/TRESA's #1 advertising complaint (audit).
Should see:
- A readiness summary (province-aware: Ontario RECO/TRESA; province set drives which regulator — never hardcode Ontario) with N-of-N required checks + advisories.
- Brokerage identity (required-to-publish): legal brokerage name + the word "Brokerage" + RECO registration # + office address + registered agent names + optional team-name co-display, with a live footer preview rendered into every page. Publishing is BLOCKED if any required field is empty — province-aware (RECO/BCFSA/RECA/OACIQ…).
- Trademark & DDF: "Powered by REALTOR.ca" linked badge (≥90px), MLS®/REALTOR® with ®/uppercase + CREA ownership statement on data pages, trademarks never in title/meta/slug/domain, accuracy disclaimer + browse-wrap ToS/privacy, "courtesy of" listing-brokerage attribution on feed listings, off-market auto-expire (~24–72h).
- Analytics: first-party (built-in, no cookies); GA4 (loads only after cookie
consent); Resend email click-tracking OFF by design (link-wrapping breaks the
vanity URLs —
feedback_consult_decision_log_wiseaiagency_click_tracking_off); Meta/Ads pixel optional. - Cookie consent & privacy (PIPEDA + Quebec Law 25): consent banner (explicit opt-in), cookie categories, QC French / Bill 96 (site + forms + consent + the AI agent in French) advisory when serving QC.
- Accessibility (AODA · WCAG 2.1 AA): automated audit on publish, public site and this dashboard.
- Hosting & domain: Canadian region + cross-border AI-vendor PIA inventory; custom domain (DNS-pending state honest); bring-your-own embed snippet.
Should NOT see:
- A Publish that succeeds with brokerage identity empty (HARD block).
- A cosmetic "all green" when a required check actually fails.
- Resend click-tracking silently re-enabled (it's off by design).
- A new embed cdn domain invented — ⚠️ carried-forward flag: the mocks use
inconsistent illustrative embed hosts (
cwa.ai/embed.jshere vscdn.wiseairealtor.com/widget.jsin agent-config). The real BYO embed uses the existing chatbotdata-business-idembed infrastructure (ai-front-desk.md§C1); reuse it, do not introduce a new domain.
Success: an account with empty brokerage identity cannot publish; filling it (province-aware) clears the gate and the identity renders into every page footer.
5. Empty / loading / error states
| State | Expected output |
|---|---|
| No site yet / first run | Template picker + onboarding ("pick a template to start") — never a blank builder (anti-pattern #6). |
| Missing-meta page | The page row shows a "No meta" warning (the Norwich example); publish of that page nudges to fix SEO. |
| Brokerage identity incomplete | The compliance summary shows the failing required check; Publish is disabled with the reason. |
| Loading | Page-list / editor / compliance skeletons, not a spinner (anti-pattern #7). |
| Save/publish error | Non-destructive inline error; draft preserved; a draft_* constraint 500 is surfaced (debug via Supabase get_logs service=postgres — §9). |
| Domain DNS pending | Honest "live at the john316.church URL until DNS verifies" — not a fake "verified". |
6. Carried-forward constraints (consistent across the batch)
- Aria does NOT book/schedule; the Contact page's AI front desk captures
showing requests (
ai-front-desk.mddecision 4). - SMS off-by-default + consent-gated; crisis/safety never gated.
- 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 — gate by role/module.
- Honest metrics/state; language never hardcoded (per-language pages = tenant languages); reuse the existing chatbot embed, not a new cdn domain.
- MVP ships no commission/GCI (N/A to this screen, but consistent).
7. Accessibility (AODA → WCAG 2.1 AA) — and the site this screen produces
- The builder itself is AA: page list + drag-reorder keyboard-operable (with a move-up/down alternative), editor controls + device toggle + compliance forms labelled, focus managed in the focus editor; status/SEO badges convey by text.
- The published site must pass AA (the Tracking & Compliance AODA audit gates it): contrast, image alt-text, keyboard nav, focus states, heading order, form labels — on the public site and this dashboard (audit must-have).
- Contrast ≥4.5:1; gold accent only; teal 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; assert change.
// Pages manager
test.fixme('Pages library mirrors /s/[slug] sub-pages incl. nested area guides + utility pages; drag sets nav order', () => {});
test.fixme('each page shows status + tenant-language chips + SEO/GEO; a "No meta" page is flagged (Norwich)', () => {});
// Focus editor (extends shipped WebsiteEditor)
test.fixme('Edit launches the focus editor (blocks|canvas|properties+Aria fair-housing guard); autosave + Draft→Publish', () => {});
test.fixme('save drives the existing draft_* pipeline; a new section/enum widens BOTH draft_* and published constraints', () => {});
// Brokerage-identity GATE (WS11 hook)
test.fixme('Publish is BLOCKED when brokerage identity is empty; province-aware (RECO/BCFSA/RECA/OACIQ, not hardcoded ON)', () => {});
test.fixme('brokerage identity renders into EVERY page footer (live preview matches published)', () => {});
// Trademark/consent/AODA/hosting
test.fixme('MLS®/REALTOR.ca badge ≥90px + "courtesy of" + off-market expire on feed listings; trademarks never in title/meta/slug', () => {});
test.fixme('GA4 loads only after cookie consent; Resend click-tracking stays OFF by design; first-party always on', () => {});
test.fixme('AODA audit gates publish for the public site AND the dashboard; Canadian hosting region honest', () => {});
test.fixme('BYO embed reuses the existing chatbot data-business-id embed — no new cdn domain invented', () => {});
// States + a11y
test.fixme('empty/missing-meta/identity-incomplete/loading/save-error/DNS-pending states render per §5', () => {});
test.fixme('builder is keyboard-navigable (reorder alternative, labelled forms); produced site passes AA; reduced-motion honored', () => {});
9. Guardrails for agents building against this spec
- Rule #17 not satisfied — do not build until founder approval.
- Extend the shipped
WebsiteEditor+RealEstateSiteTemplate+ guides — do NOT rebuild (do-not-reinvent.md). Website is a pillar in the one backend, not a separate app. draft_*twin-constraint trap — the editor saves todraft_*columns with their own CHECK constraints; a new section/enum value must widen BOTH thedraft_*and the published constraint or the save 500s for every tenant (feedback_draft_twin_constraints_must_match; debug via Supabaseget_logsservice=postgres). Migrate-before-use (Rule #18); founder-gated DDL.- Brokerage identity is a HARD publish gate — province-aware, block on empty (WS11 compliance hook). Resend click-tracking stays OFF by design.
- Reuse the existing chatbot embed, not a new cdn domain; Aria books nothing; language never hardcoded; AODA AA on builder + produced site; verify on the real host; 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) hosted vs
bring-your-own website mode surfacing (the "both tiers" decision — collapse Website
to an "AI embed + connected site" module for BYO); (2) the canonical embed
host/snippet (reconcile the two mock domains to the existing chatbot embed); (3)
how much of the compliance dashboard is agent-editable vs management-restricted (brokerage_owner/broker_admin/team_admin); (4)
French/Law-25 scope for QC tenants.