Every page in this app was read line-by-line, once, in one pass — not summarized from memory. For each one: what data it actually reads (real fixture, real computed value, or a live external call), what's genuinely wired up versus decorative, and where the two disagree. Settings' real gaps got fixed the same pass; the Client Portal got built new. Everything found outside those two is listed here as an open punch list, not silently patched — this document is the source of truth for what "done" actually means on this build, module by module.
closingboss.io/docs/implementation-specEvery route in the app — the public site, the agent dashboard, all six CRM modules, the four-part Marketing engine, Insight, all nine Settings pages, and the new Client Portal — was audited against three questions: does every displayed fact trace to real fixture data or a real computed value (never a frozen literal that should be dynamic)? Does every button/form/toggle actually change real state (never a silent no-op)? And where a real capability genuinely can't exist yet — no backend, no auth, no live payment processor — does the page say so, instead of pretending?
/portal/[token], States A & Bcrm/ directory deleted — orphaned pre-respec pages nothing linked to, found while getting a clean build
This was the worst-off area found anywhere in the app — not under-featured, actually
broken. The theme picker used an uncontrolled defaultChecked radio with
no state, so clicking a different swatch never visibly changed the selection. The
About form, the domain Add form, and the account Login form all had no
onSubmit at all, so clicking Save triggered a native browser form
submission — a full page reload that silently discarded whatever was typed. Several
buttons (logo upload, photo replace, copy link, testimonial toggle) had no
onClick whatsoever.
LogoUploader/PhotoUploader/ThemePicker/AboutForm components), matching the wireframe-state-only convention SocialLinksEditor already established on this same page.DOMAIN_SETTINGS.defaultDomain instead of a private, drifted "closingboss.io/dave" literal. Copy link is real. Card fields (phone/email) now have a working Save form and read/write the new single-source AGENT.phone/AGENT.email fields instead of three independently-typed copies of the same strings across three files.planLabel(AGENT.plan) helper instead of a second, disconnected BILLING.plan string that Team's own plan gate never agreed with. Update card opens a real inline form. Change plan links to Team (the one real place a plan change actually leads for a single-plan product) instead of faking a self-serve switcher.NOTIFICATION_SETTINGS fixture with real toggle state.AGENT.email; the form has a real onSubmit with a saved confirmation instead of a page-reloading native submit.
Two genuinely un-buildable actions — QR code download, invoice PDF download — get
honest click feedback (a real, disclosed "not wired in this wireframe" response)
instead of either silence or a fabricated file. tsc, lint, and a full
production build all pass clean.
Lives at /portal/[token], entirely outside the agent-facing (app)
shell — no left rail, no internal nav. A real portalToken field resolves
each link to a real contact; it's a real lookup, explicitly not a claim of
real security (no cryptographic randomness, no expiration, no auth system anywhere
in this codebase to back one).
TRANSACTION_CHECKLISTS data/site/valuation and
both forms on /site/contact (send a message, schedule a consultation)
have no onSubmit, no "use client", and no name
attributes on their inputs. Clicking submit triggers a native browser form
submission — the page reloads and everything a visitor typed is silently discarded,
with no error and no confirmation. These are the exact three moments this product
exists to capture, and right now none of them work.
preventDefault + local confirmation pattern already proven in ShowingRequestButton.tsx.
Once wired, a real submission genuinely can't reach the agent's Inbox — there's no
shared store between the public site and the dashboard yet, the same disclosed
architecture limit that applies everywhere else in this app. The honest ceiling here
is a local "got it, Dave will follow up" confirmation, matching what
ShowingRequestButton already achieves. Right now these three forms don't
even reach that ceiling — they just silently fail.
Smaller finds in the same cluster: the AI chat bubble (present on every public page)
has buttons that do nothing at all, not even a canned reply, despite already having
local state wired up and an honest "Wireframe — not connected yet" caption printed
right next to them. The homepage's Showcase section doesn't disclose that its listings
come from a SimplyRETS trial-dataset agent ID standing in for Dave's real MLS ID, the
way the equivalent code in /spotlight already does. And the About page
overstates what /site/search actually shows ("straight from Dave's own
MLS feed" — it's actually the whole board, other agents included, which is why every
result already carries a "Listing courtesy of" line).
Worth naming clearly: this is not a fixture. /spotlight reads and
writes a real Postgres table (showcase_overrides, RLS enabled) via real
server actions, merged with live SimplyRETS API calls. The bugs found here are real
bugs in real, working infrastructure — not disclosed-absence gaps.
Inbox, Pipeline, and Calendar came back completely clean. Two real, narrow bugs found elsewhere in the cluster:
dueInDays ?? 999, used to push undated finished checklist steps to the back of the queue) leaks into the actual displayed date. Elena Rostova's three already-completed, never-dated inspection/appraisal steps render with a fabricated date roughly 999 days out — the Completed tab can show something like "May 5 · Today" for a step that has no real due date at all.Smaller nit, same root cause in four places: the Contact "Source" dropdown's six option values are independently hand-typed in four different files with no shared fixture array backing them — a maintainability risk, not a functional break.
Documents and Listing Graphics came back completely clean. Listing Alerts is the most transparent page in the entire app about what's missing — its own hero copy says "Nothing here sends an email today," on-screen, not just in a code comment. The real gaps found are narrow:
value or onChange; the submit handler only closes the panel — it never reads what was typed and never appends anything anywhere. TRACKING_LINKS is a plain module-level constant, not React state, so there's structurally nowhere for a created link to go yet. The stat tiles and the link list are genuinely real and correctly wired; only creation is fake."closingboss.io/dana" — every other place in the app that shows a public short link (the digital card, both lead-capture public URLs) uses "closingboss.io/dave", the real agent. Every link and every clipboard copy this page produces is visibly wrong for this account.| Priority | Where | What |
|---|---|---|
| 1 | Public site | Wire the 3 dead lead-capture forms (valuation, contact ×2) — the product's actual entry points don't work today. |
| 2 | Spotlight | Dedupe synced/added listings by ID; fix the missing revalidatePath on Remove. |
| 3 | Insight | Wire Tracking Links' create form to real state; fix the wrong "dana" domain literal. |
| 4 | Tasks | Stop the sort-sentinel date from leaking into the display for undated completed items. |
| 5 | Contacts list | Replace the fake "Send e-sign" log entry with a real deep-link into the Documents wizard. |
| 6 | Marketing | Add a real delete-campaign action; force the first drip step's delay to zero. |
| 7 | Site & Listing pages | Fix the two disclosure/accuracy copy issues (demo agent ID, "own MLS feed" overstatement); wrap the listing-detail fetch in the same try/catch the home/search pages already use. |
Client Portal's State C (multi-transaction switcher) isn't on this list — it needs a real product decision about extending Contact beyond 1:1 with Deal, not a fix, and that decision touches Pipeline too.