Everything the backend does
58 shipped features, each with its own page: what it does, how to turn it on, and the API your front end calls. Build the front however you like — by hand, or with Lovable, v0, Bolt, Claude, or Cursor — and connect it to a backend that already has auth, a multi-tenant database, payments through your own Stripe, and email/SMS.
Customers & revenue
The records and money paths your front end reads and writes: contacts, leads, pricing, orders, the ledger.
Member personal contact list
The member's own address book — people saved from event badge scans plus manual adds. Person-scoped (follows the member across organizations, never the org's CRM); add is idempotent per email; remove is owner-authorized soft delete. External ids are opaque public_identifiers.
Lead-capture landing page (public marketing front door)
A per-company public landing at /lp/:portalSlug a business links from ads, QR codes, and outbound messages. Pulls the org's branding from the public portal bootstrap and captures first name / email / phone with NO password — the passwordless POST /member/signup find-or-creates the crm_contact behind the scenes, so every capture lands in the CRM. Falls back to a 'get in touch' card when the org has self-signup off. STOPGAP: a lightweight no-account POST /public/leads is a backend ask; when it ships, point the form there.
Pricing (view + guide)
View an organization's active prices from the rule engine, joined so each row reads as what-it-prices / value / since-when. Money is a NUMERIC(18,6) string; currency renders via MoneyDisplay, other rule values show their unit. A plain-language guide (/pricing/guide) teaches the real engine — rule types, values, versions, the planner, and kept-forever history — so a person or an AI can follow the same model. Setting/adjusting prices, the planner, history/trends, and CSV/AI import are later phases (SP-PRICING-MANAGEMENT-V1); the save path waits on a backend response-envelope fix so no button false-errors.
Pricing history + close-price
How prices got to where they are: the immutable change log (every create/close with before/after values, kept forever) plus the one lifecycle action a price supports — Close (L-RULE-1: values are never edited in place; close + create is the only change). Money renders via MoneyDisplay from the L-MONEY string.
Refunds + commissions on Finance
Record a refund against any recorded payment (per-row action; the ledger records the reversal — amounts stay L-MONEY strings, idempotency-guarded server-side) and see commission records as jobs complete, with the rule definitions behind them.
Ledger — chart of accounts + entry drill-in
The ledger page rounds out: the chart of accounts (code, name, type, normal side) and a drill-in on every journal entry showing its balanced debit/credit lines per account — the visible proof of double entry. Money stays L-MONEY strings through MoneyDisplay.
Customer statement (printable)
One customer's whole money picture on a page: their orders, the payments received against each, and every order's ledger-computed balance (GET /fin/orders/:id/balance — the ledger is the arithmetic authority; the page only displays strings). Print produces a clean statement — all app chrome is print-hidden.
Print-ready quotes & invoices
A Print button on the order detail produces a clean quote/invoice: the shell (nav, top bar, demo bar), header actions, back-links, and the fulfillment panel are all print-hidden, leaving the line items, totals, and ledger balance — what a customer should see on paper. The same print foundation (kit PageHeader actions never print) serves every future printable page.
Billing & plan
The org's platform subscription on the record: plan, status, current billing period, and the last three invoices with per-line L-MONEY amounts (plan / extra seats / AI credits / total). Read surface — plan changes run through the platform's processor flows, not template forms.
Request detail — responses & connect
The closing half of the need board: open a posted request, read provider responses (record one from a network partner, mark viewed), then connect with the winner — the request settles to 'connected' — or withdraw it from the board.
Match profile editor — how you get matched
The explainability seam made editable: the facts the matching engine ranks providers against (vertical, revenue band, team size, state) in a 'How you get matched' editor on Discover. Full-state save — engine-owned tiers/scores pass through untouched so the write can't clobber them.
Operations & scheduling
Turning agreements into work that happens: jobs, dispatch, the week view, trust actions.
Dispatch board (crew assignment)
Drag-free dispatch: see scheduled field jobs alongside your team roster and assign/unassign crew per job (POST /dispatch/assignments). The board reads the same ops jobs the Field Ops page manages, so dispatchers and schedulers work off one truth.
Field job creation + visits & territories
Schedule a field job from the web: pick the service agreement it fulfills (jobs bill against agreements), set the date, add crew notes. Plus compact read panels for recent field visits and defined territories — the web could previously complete jobs it couldn't create.
Schedule — the week on one board
A 7-day week view of field jobs and events — the 'where's my week' screen every field-service owner asks for first. Read view over GET /ops/jobs + GET /events (no new API); week navigation, today highlighted, every card links into its detail surface. Mobile-first: day columns scroll horizontally with snap on phones, full grid from md up.
Trust actions — place/release holds, open disputes
The confidence layer's verbs: place an escrow hold on an order (money as an L-MONEY string, held until released), release a held hold with a recorded reason, and open a dispute on an order. Reads were already live; this adds the actions.
Automation runs & approvals
The other half of Automations: run history per lifecycle state with cancel, plus the approvals queue — the human gate an automation pauses on before any money-moving or irreversible step (approve releases the dispatch; reject routes to the failure path).
Operating guide (how your business runs here)
A plain-language walkthrough of the whole operating loop (acquire → qualify → quote → agree → fulfill → settle → understand), each step linking to the page that does it, plus a map of how the modules connect and a pointer for a partner's AI. The 'how we do things' reference that lets a person or their assistant follow the business end to end.
Audience, events & members
Public surfaces that turn visitors into known people: events, passes, portals, magic links.
Upcoming events summary
Operator page listing the organisation's upcoming (non-terminal, not-yet-ended) events in chronological order. Filters completed and cancelled events out client-side; sorts by start date. The 'View attendees' CTA is gated on event.attendee.read.
Public event reserve page
A visitor (not a member, no login) reserves a spot at an event from a shared link — org resolved server-side from the event id, IP rate-limited. Standalone page, noindex, no dashboard chrome.
Attendee claim landing (magic link)
Where the 'claim your profile' email lands: /claim/:token verifies the 30-minute HMAC claim token, provisions the person-owned Groundwork identity (idempotent — a re-clicked link greets the existing person), signs them in, and points them at their professional profile.
Customer pass / entitlements page
A signed link a customer opens to see their entitlements — no account needed. The link IS the authorization (opaque token in the URL).
Sponsor / exhibitor portal
Event sponsors get a tokenized self-serve page for their booth/sponsorship details — no account, the opaque token is the key.
Member (customer) portal
A per-tenant, capability-gated customer portal at /m/:portalSlug: sign in/up, dashboard, events, courses, orders, refer-a-friend, coach, account. Separate session from the operator app.
Member magic-link sign-in
Passwordless sign-in for portal members: request a one-time emailed link at /m/:portalSlug/magic; the link lands back on the same route with ?token= and signs the member in (session cookie set server-side). Single-use, org-scoped, no account enumeration.
Member event self-registration
A signed-in member registers themselves for a free, registration-open event from their portal. Idempotent; paid events are directed to checkout (never mints an unpaid order).
Member-portal settings
Configure the customer-facing portal: branding, welcome message, self-signup toggle, capabilities. What you set here is exactly what /m/:slug and the /lp/:slug landing render for your customers.
Operator referral-program management
An operator creates/edits the org's referral program (rewards, conditions). One active program per org; reward values are money-strings.
Marketing, content & discovery
How people find you and what they read — including how AI assistants read your site.
Public marketing website
The public front-door site: home, services, about, and a contact form. Token-driven + skinnable, mobile-first, with a config-driven nav. Public (no login). Analytics fires on these pages automatically. '/' is the marketing home.
Public blog
Public blog (list + post pages). Content from lib/content/blog.ts (edit posts or swap to a content API). Toggle via the marketing nav. Surfaces: /blog, /blog/[slug].
Blog syndication + taxonomy (RSS, tags, related, reading time)
RSS 2.0 feed at /feed.xml (advertised via metadata alternates, public in middleware), lowercase topic tags on posts with chip navigation and statically-generated /blog/tag/[tag] archives (sitemapped), shared-tag related-posts on every article, and reading-time estimates on cards and posts. Built entirely on the getPosts()/getTags() swap points, so the whole surface flips to DB-driven automatically when the content_ CMS lands — the named P2 fast-follow, shipped early on the static source.
Public FAQ accordion
Public FAQ accordion. Content from lib/content/faq.ts. Toggle via the marketing nav. Surface: /faq.
Analytics & tracking
Drop a Google Analytics (GA4), Google Tag Manager, or Meta Pixel ID into the config and tracking works on every page. The Content-Security-Policy opens only for the providers you enable; blank IDs load nothing and the CSP stays locked.
Referral & UTM attribution
Captures where a visitor came from — a referral code (/r/CODE or ?ref=) and utm_* campaign params — into a first-touch cookie, and attaches it to leads (the contact form today, flow intake later) so they're credited to their source. GA reads utm_* natively too.
SEO + AI-searchable foundation
Per-page metadata (lib/seo), schema.org JSON-LD (organization, website, FAQ, BlogPosting via lib/jsonld + XSS-safe JsonLd component), a full sitemap.xml (marketing + blog + industries, toggle-aware), robots.txt, and /llms.txt — the emerging AI-crawler descriptor (llmstxt.org) generated live from config + content so answer engines (ChatGPT, Perplexity, Claude) can understand and cite the site. Content sources expose clean getX() functions explicitly designed to swap static→CMS/API with no page changes.
Terms of Service + Privacy Policy (starting-point templates)
Public /terms and /privacy pages pre-filled from site.config (company name + contact always right), each carrying an on-page 'have a lawyer review this' notice you remove after legal sign-off. The privacy policy honestly describes what THIS stack collects (account details, CRM records, feedback with page context, session/theme/locale cookies) so it starts true. Footer links + a consent line ('by creating an account you agree to Terms & Privacy') on all three signup surfaces (operator, member portal, lead-capture landing).
Industry showcase pages (optional, data-driven)
Public /industries/:slug landing pages tuned to a vertical (lawn care, cleaning, home services, events out of the box) — each is one object in lib/content/industries.ts, so adding/removing an industry is a data edit, not code. The whole section is a config toggle (siteConfig.optionalPages.industries): off → the routes 404 and the nav link vanishes. The pattern extends to any optional feature area.
Editorial kit: StructuredTextEditor + PublishBar + TranslationTabs
The universal editing components for editorial content (LWS P2 kit half, content_-agnostic by doctrine): StructuredTextEditor edits paragraph-array bodies with the blank-line-= new-paragraph mental model (no HTML smuggling — the renderer owns typography); PublishBar is the draft→published human gate, permission-gated (hide-not-disable) with the permission key as a prop so any module can mount it; TranslationTabs shows per-locale publish coverage (EN+ES) with a visitors-see-fallback note. All prop-driven, zero API coupling — the dashboard content editor composes them once the content_ endpoints land.
Drive — files & folders
The permissioned folder tree over the file_ platform (/drive, nav-seated, file.read): Company Drive and My Drive tabs, breadcrumb navigation, create/rename/delete (empty-only) folders, per-folder file lists with scan-status badges and signed-URL downloads, and the org storage meter. Mutations cosmetically gated on file.write (hide-not-disable); the service enforces the per-drive write-vs-admin rule — the API is the wall. Demo-mode fixtures included.
AI, insight & automation
The coach that reads your live data, the signals it raises, and the feedback loop that teaches it.
Coach — act feedback + signal periods
Closes the Coach's feedback loop: 'I acted on this' on every insight (the engine learns which advice lands) alongside Dismiss, and the signal view gets a working 7d/30d/90d period selector over the live signals endpoint instead of a fixed 30-day pill.
In-product feedback + the owner's improvement inbox
Send feedback lives in the user menu on every page: bug report or feature request, a text box, and the page URL/route/title captured automatically (signal module). The owner triages at /settings/feedback — filter by type/status, read in context, and resolve with In review / Planned / Resolved / Won't fix; feature requests carry votes. Screenshot attach arrives with the doc_ module (proposal 47d03354).
Coach credits & top-up
Balance, usage history, and purchasable credit packages for the Coach (checkout via POST /coach/topup). Pairs with the Coach chat's upgrade CTA.
Reports hub
The owner's numbers on one page: revenue by month, pipeline value by stage, lead sources, field-job status, and event attendance — every panel a view over endpoints the app already calls, charted with the dependency-free kit BarChart, and every panel exports its rows as CSV (money verbatim).
Notifications inbox
Updates from your team and your work in one list (GET /comms/notifications), mark-as-read per item. The bell in the shell header deep-links here.
Messages — org-wide log, compose, opt-out list
One place for everything sent to contacts across email/SMS/push: the org-wide message log with channel filter, a compose modal for direct sends, and the opt-out (suppression) list — visibility only, since the platform refuses suppressed recipients at send time. Per-contact threads stay on the contact page.
Platform, design & tooling
The kit, the theming, the multi-organization spine, and the developer tooling around it.
Design-system component kit
Owned (copy-don't-import) UI primitives under @/components/ui: Button, Card, Input, Field, Label, Switch, Tabs, Alert, Badge, StatusBadge, Modal, Table, MoneyDisplay, states, PageHeader. All token-driven.
Theming & skinning
Re-skin the whole site by changing a small set of brand tokens. All colors flow through semantic CSS variables (surface/content/action) across 5 color schemes (light, dark, high-contrast, outdoor, system).
Curated public brand palettes
Pick the site's brand from a curated palette set (site.config tenant.brandPalette: blue/navy/slate/teal/emerald/forest/rose/orange/violet) — colors designed to work together and machine-proven legible on the PUBLIC pages (link text, CTA fill + hover, focus ring) by the extended check-theme-catalog.mjs public-surface proof. Custom hex (brandColor) stays as the escape hatch, now with an auto-derived CTA text color (readableOn) so even a light custom brand can't ship an unreadable button. Palette resolution also drives the generated favicon, OG image, and PWA theme color, so assets always match the live brand.
Config-driven module navigation
Turn app modules on/off and reorder the nav by editing one file. The nav is derived from NAV_CATALOG filtered + sorted by site.config.ts modules.
Appearance settings (theme + language)
Pick your color scheme (light / dark / high-contrast / outdoor / follow-OS) and language (EN/ES). Persists in cookies the middleware reads, so the choice survives reloads and applies before first paint.
Roles & permissions admin
The reusable RBAC-admin example: member list with roles, effective permissions with role-vs-override provenance, grant/revoke overrides, plus a guide page explaining the model. The page partners copy when they need admin surfaces.
Add an organization (seed a prospect)
An operator seeds a prospect organization — a lightweight pricing-anchor stub for a business that isn't a Genesis customer yet — so they can price against a real organization_id. The referred owner's email is captured (optional but encouraged) as a future claim key; no login or role is created. Brand/marketing/naming for the seeded org inherit from the caller's white-label root (resolved by the backend + comms layer, not chosen on the form).
Owner Coach — Getting started
An in-app setup coach for the business owner (the companion to docs/quickstart.md, which coaches the developer/AI). A grouped checklist of setup steps — brand, connect data, turn on features, invite team — each linking to the real in-app page that does it, with a progress bar. DRAFT: steps come from a typed local source (lib/content/onboarding.ts); completion is tracked client-side (localStorage) until an onboarding-status API derives it from real signals.
Global search
One search box over your contact database (GET /crm/search) with keyboard-first UX — type two characters and go. The pattern page partners extend to more domains as cross-domain search lands server-side.
Command palette (⌘K)
Press ⌘K / Ctrl+K anywhere to jump to any page or fire a quick create-action (new contact, quote, lead, message). Fuzzy-filter, arrow-key navigation, Enter to go, Esc to close. Reuses the same permission-gated NAV_CATALOG the sidebar uses, so it never offers a destination the user can't reach. Pure FE, keyboard-first, screen-reader labeled, EN/ES.
CSV export (contacts + orders)
Get your data out: one-click CSV downloads on the contacts and orders lists, built client-side from the rows the page already holds (RFC 4180 quoting, UTF-8 BOM for Excel, money written as the L-MONEY string — never parsed). The shared helper lib/csv.ts is the pattern for any list page.
Demo mode — the whole app with no backend
Set NEXT_PUBLIC_DEMO=1 and every page renders believable sample data (fixtures at the typed-client seam, lib/demo/fixtures.ts) with no Genesis API and no login: dashboard brief, CRM leads/contacts/pipeline, orders + balances, events, field ops, learning, messages, ledger, workflows, and the member portal. Writes are refused with DEMO_READ_ONLY so forms exercise their real error paths. Fixtures honor the API contract — L-MONEY strings, opaque ids, live status vocabulary — and a test suite (lib/demo/fixtures.test.ts) enforces it.
Demo conversion CTA (the giveaway funnel)
In demo mode, a persistent bar turns the tour into a funnel: the big CTA (Start your real business) sends people to platform signup (NEXT_PUBLIC_SIGNUP_URL on hosted demos), and a three-step explainer tells the giveaway story — clone the free MIT template, brand it (AI prompts included), connect your Genesis organization and every page lights up with real data. EN/ES.
Mock API service (zero-backend dev + runtime API-path proof)
pnpm mock runs the whole front end with no backend: envelope fixtures for /api/v1/* (mock/fixtures.json), the app, and a same-origin proxy on one port so the REAL CSP (connect-src 'self') and cookie scoping hold. For humans without credentials and for AI agents (Claude Code/Chat) that need to render, screenshot, or test pages. --strict turns undeclared endpoints into hard 501s and GET /__mock/report answers 'what does the FE actually call, and is all of it declared?' — the runtime counterpart of the static raw-fetch + openapi-coverage gates. Docs: docs/mock-api.md.