How people get into PURE — five doors, one policy
Since public self-signup is now off, everyone who touches PURE comes through one of five sanctioned, invitation- or admin-controlled doors: staff & agents are invited, clients are brought in by their agent to their own Transaction Hub, vendors are pulled into the deals they serve, prospective clients are captured as leads (no account), and Dave's testers are issued seats. This is the canonical reference for each — and the unifying rule underneath them: one identity, many hats; you see only the rooms you're a party to (pure_my_rooms + RLS).
What changed — 7/7/26
Sign In / Providers “Allow new users to sign up” = OFF. New platform accounts are now created by invitation / admin only. Current base: 36 users (all confirmed, 9 have signed in, 0 anonymous). This change does not affect lead capture (leads aren’t accounts) or Test Drive (guest journeys + admin-minted sandbox logins) — both verified below.
Login methods — lean by design
Two providers are enabled; everything else stays off. Fewer providers = less attack surface and a cleaner sign-in.
Enabled now
Email (password and passwordless magic-link) and Google. Magic-link is the low-friction door for clients & vendors — no new provider needed.
Future (ticketed, not now)
Phone / SMS OTP — great for clients, blocked on Twilio A2P (Katy's lane). SAML 2.0 / WorkOS — only when an enterprise org (big brokerage / MLS / association) needs SSO. Apple / Microsoft optional later for consumer/agent convenience.
Staff & Agent Onboarding — invite-only
Give a real person (staff, agent, or org admin) a platform login. This is the only path that creates an auth account, and it now always starts with an admin invitation.
- Admin provisions the person. Grant a scope in pure_admin_allowlist (e.g.
poppy_user) and send the invite via Supabase Auth (inviteUserByEmail/ admin create). This fires the branded invite email (theinvitebranch of theauth-email-hook).Invitations work even with public signups off — that’s the point. - Invitee sets a password. The invite lands them on poppy-welcome.html?who=<name> (or sign-in.html) to self-set a password.
- Confirms email. Required before first sign-in — handled by the branded confirm-email template. Blocks typo/fake addresses.
- Enrolls MFA (AAL2). TOTP or passkey at sign-in; MFA prompt appears automatically once the person’s org has
mfa_required=true. - Chooses hats (first-run). welcome-hats.html: verify identity claim hats (broker / client / association / staff — auto or manual-approval) writes identity + roles.
- Lands on the platform. Routed to /pure-home (or
/poppy). Proof-of-onboard = a hello ticket on pure_board.
Leads & Marketing
Capture a prospective client or market PURE to org buyers. Leads are records, not logins — they never touch the auth system, so the signup policy is irrelevant here.
Track 1 · Consumer / prospect lead (public)
- Visitor hits a capture surface — seller form (list-your-home.html), a “Get started” / contact form, open-house check-in, or a listing inquiry.
- Form calls
mcp_lead_create(p_name, p_source, p_type, p_principal)— anon-executable, so no login required. De-dupes by email + phone. - Lead lands in leads / pure_leads; activity logged in pure_lead_intake (stage / owner / by-who).
- Routing (pure_routing_rules) assigns/rotates to an agent; speed-to-lead ladder + first-to-claim.
- Agent works it in CRM converts to a deal.
Track 2 · Marketing PURE to orgs (B2B)
The Pure Growth command center (Pure Growth.html) + the daily 7am Morning Digest market PURE to its buyers — MLS, Associations, Brokerages.
Data-driven briefs per audience regenerate daily from pure_growth_brief and pure_digest (pages read live — no redeploy to refresh content). Owner: Cecile (design + comms + marketing lead).
This is outbound (we market to them). Inbound interest from these audiences still lands as a lead via Track 1.
mcp_lead_create. If not, that’s a small, self-contained build — flagged as the next item. ~10,800 leads are already in the funnel via existing ingest points.Test Users — Dave’s Tester Unit
Let Dave’s reviewers and testers exercise PURE across roles and journeys without real accounts and without touching live data. Two modes, both admin-controlled.
Mode 1 · Guest Test Drive (no login)
mcp_testdrive_create(name, email, surfaces[], when, persona='guest') issues a guided journey over seeded / sample data.
Runner: pure-testdrive.html · Admin: pure-testdrive-admin.html (mcp_is_admin-gated).
Guest = no password the signup policy doesn’t apply.
Mode 2 · Reviewer sandbox logins (admin-minted)
The DAVE-SANDBOX suite: revocable multi-role demo logins, recorded sessions, reset-to-clean, read-only PII.
mcp_sandbox_mintmcp_sandbox_loginmcp_sandbox_recordmcp_sandbox_resetmcp_sandbox_revoke
Isolation via is_demo=true + sandbox_ns; mcp_purge_demo() / mcp_testdrive_purge(keep_logs) wipe test data, keep logs, leave live tables untouched.
mcp_sandbox_mint), not self-signups, so turning off public signups does not block Dave’s testers. Guest test drives need no account at all. Both issued from the Pure Admin Console Test Drive Admin.Client Access — see your Transaction Hub
A client (buyer / seller / landlord / tenant) gets a scoped login, invited by their agent, and sees only their own transaction(s) — the same Transaction Hub the agent works, filtered to their deal. They never self-register.
- Agent invites from the deal. Inside the Transaction Hub, “Invite client” mints a scoped account (branded invite email — signups-off safe) or a passwordless magic-link, and links the person as a party. pure_room_parties transaction_parties pure_associations
- Client sets access. Password or magic-link (low-friction); email confirm required.
- Light MFA (optional). Clients can be lower-friction than staff — governed per-org, not forced.
- Lands directly in their Room. Deep-linked into the Transaction Hub filtered to their deal(s) via
pure_my_rooms— not the full staff nav. - Sees their slice only. Documents (pure_room_docs), milestones (pure_room_timeline), tasks (pure_client_tasks), signatures, showings — for their deal(s), enforced by RLS (
auth.jwt email = party).
mcp_room_invite(deal_id, email, role) that mints the scoped account and links the party; (2) RLS policies scoping the room tables to external parties by JWT email; (3) client deep-link landing straight into their room post-login.Vendor Access — their slice, in-system
Vendors (title, lender, inspector, appraiser, photographer, referral companies) are pulled into a transaction as a role and see only their permissioned slice of the deals they’re on — and deliver their work back inside PURE, not by email.
Model 1 · Per-deal guest
Invited to a specific deal for their role (title / inspector / lender…); sees only that deal’s relevant section; magic-link or scoped account. Fast, disposable.
Model 2 · Persistent vendor org
Referral companies / title cos as level-5 orgs with membership they log in and see all their PURE deals in the Vendor Portal. Seeded is_demo=true first, flipped real after review.
pure_my_rooms + RLS by party role. This is the “three views, one record” model: the exact same deal rendered as broker / client / vendor. Vendors deliver back (upload deliverables, update status) — the portal is two-way, not read-only.fable-vendorportal) wired live to pure_my_rooms / pure_vendor_jobs; (2) vendor-role RLS slice (role determines which sections show); (3) referral-company level-5 orgs (is_demo first).State & open items — as of this snapshot
| Area | Status | Detail |
|---|---|---|
| Auth signups | Verified OFF | 36 users, all confirmed, 9 have signed in, 0 anonymous. New accounts = invite only. |
| Invite / confirm / MFA emails | Live | Branded via auth-email-hook v14 (Open Sans, dedicated MFA code email). |
| Lead capture (public) | Live | mcp_lead_create is anon-callable; seller path (list-your-home) wired; ~10,800 leads in funnel. |
| Buyer / general lead form | Open | Confirm/add a public “become a client” form pointing at mcp_lead_create. Small build. |
| Test Drive (guest) | Live | mcp_testdrive_create anon; runner + admin pages live. |
| Reviewer sandbox | Live | Full mint/login/record/reset/revoke suite; admin-minted, demo-isolated. |
| Transaction Hub / rooms | Live | pure_rooms · pure_room_parties · pure_my_rooms; transaction-room.html shipped. |
| Client portal entry | Live | acquisto-portal.html — buyer / seller / current-client paths. |
| Invite-from-deal (client & vendor) | Open | Needs mcp_room_invite(deal_id,email,role) + deal-scoped RLS for external parties. |
| Vendor Portal | Open | Pull forward 4.8 fable-vendorportal live on pure_vendor_jobs / pure_my_rooms. |
| RLS enforcement | Phase 1 | Per-user/org enforced (auth.jwt email); extend to room tables for external client/vendor parties. |