Files
LynkedUpPro_CRM/docs/superpowers/specs/2026-05-29-demo-data-coherence-design.md
T

12 KiB
Raw Blame History

Demo Data Coherence & Simulation Depth — Design Spec

Date: 2026-05-29 Branch: revamp Goal: Turn the CRM's mock data into one coherent fake roofing company ("LynkedUp Pro Roofing") that works as both a live sales demo (believable, no empty/broken views, numbers that feel real) and an investor pitch (breadth, depth, analytics wow). Coherence end-to-end is the wow: drilling from any dashboard KPI lands on the exact records that compose it.

Approach: A — Canonical-company foundation, then layer up. Analytics are computed from canonical data (one curated exception: purely-visual long-range trend lines).

Sequencing decision: Data coherence first (Phases 16), then the three interactive subsystems (Phases 79).


1. Canonical identity (foundation)

Problem (audit): the same people exist under three incompatible ID schemes; cross-module lookups silently fail; Owner #2 has two names; admins have placeholder names; subcontractor tasks reference non-existent ids (owner_001, ADM01).

Decision: unify on the MOCK_USERS scheme (auth + projects already use it):

  • Owners own_001 (Justin Johnson), own_002 (Diana Reeves); Admins a1 (Adam Admin), a2 (Amanda Manager), a3 (Arthur Director); Field agents e1e5; Sales/personnel p1 (Jesus Gonzales), p2 (Sarah Sales); Contractor con_001; Subcontractors sub_001sub_005.

Changes: remap orgMembers[].userId and all subcontractor-task references (assignedBy/actorId/senderId) to canonical ids; reconcile names/emails (Owner #2 = Diana Reeves everywhere; real admin names; consistent Justin email); add a resolvePerson(id) selector returning { id, name, email, role } from a single merged index.

Acceptance: no owner_001/FA0*/ADM0* used as an id; every person reference resolves; own_002 shows one name everywhere.


2. Coherence fixes (four approved tiers)

2a. Feature-breaking data

  • Leads List page: seed leads (currently useState([])) with ~2835 records in the page's shape; never show the empty state.
  • Subcontractor access: add login user records for sub_002sub_005 so each sub's tasks/notifications are reachable.
  • Task → project: every subcontractor task points to a project whose address matches the task location; add On Hold to STATUS_CONFIG/STATUS_STYLES.

2b. Financial coherence

  • proj_008: paid invoices ≤ committedCost (52,000) and ≤ actualCost (44,500).
  • proj_005: set committedCost to the breakdown's real sum 28,850.
  • Completed projects (proj_002, proj_010): paid invoices ≤ actualCost.
  • proj_004: fix contingency line committed < actual; keep as the over-budget case.
  • Add coherent budgetBreakdown to projects missing it (allocated→budget, committed→committedCost, actual→actualCost, committed≥actual per line).
  • Variance correctness: variancePercent = (actualCost budget)/budget × 100, displayed with explicit + (over) / (under) and correct color everywhere it renders.

2c. Pipeline / Kanban

  • Structured numeric value (estimate) on every kanban lead → enables pipeline $ total + weighted funnel.
  • Fix Complete-stage leads: real actualCost, completionPct: 100.
  • Single DEMO_TODAY constant (fixed recent date) used app-wide; dates ordered, not future relative to it.
  • Populate stormSource on storm-canvassed leads; kl_044 (Signed) gets a project record or a pre-signed stage.

3. Ten demo-case projects (threaded end-to-end)

~10 projects, each a distinct real-world case, each threaded across modules with consistent identities/addresses/dates: lead → project → subcontractor task(s) → invoices/payments → commission. Each requires a matching lead (pipeline stage consistent with project status), ≥1 subcontractor task (address-matched), invoices + paymentSchedule reconciling with actualCost, a commission config (+ payout for completed), and consistent team/owner/dates.

Case matrix to cover:

  1. Storm-driven win, on track (healthy active).
  2. Insurance-backed up-scope → approved — small self-report → inspection finds major damage → revised estimate → insurance supplement → approved (the hero discrepancy story).
  3. Up-scope → customer declines (lost) — revised estimate too high; lead lost, reason "declined after inspection".
  4. Smaller/different than claimed — over-stated; inspection down-scopes to a quick small job.
  5. Multiple revisions / negotiation — several estimate versions before agreement (richest version history).
  6. Over-budget / margin loss (proj_004 — scope creep).
  7. Large commercial, multi-phase (proj_007).
  8. Near-complete, healthy (proj_008).
  9. Completed, full lifecycle, all paid (proj_010).
  10. Disputed / on-hold (proj_011).

(Existing proj_001/003/005/006/009/012 are folded in / reused where they fit a case; net target ≈10 fully-threaded.)


4. Deeper project detail tables

Every project carries the full coherent set so no tab is empty: budgetBreakdown, changeOrders, rfis, riskLog, issueLog, activityTimeline, milestones, invoices, paymentSchedule, documents, teamMembers, plus the new lifecycle/inspection/estimate data (§78).

5. Broader pipeline + leaderboard

More leads across stages with $ values + storm attribution; canvasser leaderboard stats derive from the leads each agent sourced.

6. Computed analytics (investor wow)

New src/data/selectors.js (pure functions over store arrays): pipeline value/funnel/win-rate; revenue/gross/net profit/margin (matching OwnerProjectDetail formulas); commission by rep/project; subcontractor performance; storm attribution. Wire into owner/admin dashboards so KPIs tie out with detail screens. Curated exception: long-range visual trend lines (labeled illustrative). Acceptance: dashboard headline revenue/profit/pipeline == sums of underlying records.


7. Project execution lifecycle (interactive state machine)

A lifecycleStage field per project drives a state machine; the coarse kanban stage (In Progress/Complete) derives from it. Each stage maps to a project progress %:

Stage Progress
Lead (customer's reported claim) 5%
Damage Inspection Scheduled 10%
Damage Verified (real scope captured) 20%
Scope Approved 30%
Contract Signed 40%
Work In Progress (milestone-driven) 4070%
Work Complete — Awaiting Inspection 80%
Final Inspection (Scheduled → In Progress) 8590%
Rework In Progress (issues found; regresses) re-inspects
Project Completed 95%
Final Payment Received — Closed 100%

(Stage names: proposed; user is tweaking a few — see Open Items.)

Interactivity: owner/admin advances stages (each transition may carry an optional note + timestamp + actor). Fully interactive; photo/note uploads persist for the session (client-side object URLs), with seeded starting data; placeholder thumbnails acceptable where no real file.

Inspections (two project-level touchpoints, each records who did it):

  • Damage Verification (pre-sale): performed by a field agent or sales rep — inspector recorded per project (name + role), with findings + photos.
  • Final Inspection (post-work): an external examiner brought by the customer — no login/role; we store inspectorName, inspectorContact (phone + email, so they can be re-contacted), inspectionDate, result (pass/fail), feedbackNote, and issues[] (each { description, note, photos[], status: open|fixed }). Re-inspection after rework creates a new round; all rounds visible.

Claimed-vs-verified discrepancy model:

  • Lead stores reportedScope (customer's claim: description + rough size/cost/duration guess).
  • Damage Verification produces verifiedScope (findings, photos, measurements, severity, recommended work, real cost/duration).
  • When verified materially differs, project carries a scope-variance flag; visible alert/badge on project detail (e.g., "Reported ~$200 / 1 day → Verified $15,400 / 5 days") + a flag in the pipeline.
  • Drives estimate versioning (§8): v1 rough quote from claim → v2 verified → signed = verified.
  • Decision branch at Damage Verified → Scope Approved: approved (often insurance-supplement) or declined (lead lost). All four outcomes from §3 (cases 25) represented across the 10 projects.

8. Estimate versions (tied to the project)

Each project carries estimateVersions[]: { version, date, total, note, status: sent|revised|signed, lineItems/templateRef }. List shows date/note/total + a Signed badge; clicking a version opens the full rendered estimate document (reusing existing estimate/template rendering). Visible on owner project detail and pipeline lead-project page. v1 reflects the customer claim; later versions reflect verified scope.

9. Subcontractor task stage machine

Status set (replaces flat Assigned/In Progress/…), each transition carries an optional note + timestamp + actor: Not Assigned → Assigned → Pre-Work Inspection → Work In Progress → (On Hold ↔) → Post-Work Review →Pass → Completed / ↳ Fail → Rework Needed (issue: what's wrong + note + photo) → back to Work In Progress → re-review.

  • Inspector attribution: Pre-Work Inspection and Post-Work Review each record who performed them.
  • Owner /owner/subcontractor-tasks table gains columns Task Category and Assigned Date.
  • Task detail modal: richer progress — stage timeline, current stage + who/when, review results, issues list with photos.
  • Same task + stage visible in the subcontractor's own login; sub can advance self-stages / log rework issues.

Coherency map (everything ties to a real project)

  • Subcontractor task → real project → visible in sub login + owner project Team/Tasks tab + subcontractor-tasks page.
  • Estimate versions → the project's signed estimate is the deal (matches lead's Estimate Sent/Signed pipeline stage).
  • Lifecycle/inspection/issues/scope-variance → live on the project; surfaced on owner detail, pipeline lead-project view, and dashboard counts.

Components / files touched

  • src/data/mockStore.jsx — identity remap, leads seed, financial fixes, breakdowns, 10 threaded scenarios, sub logins, deeper tables, pipeline values, lifecycle/inspection/estimate/scope data, sub-task stage data. (Large file; surgical/additive edits.)
  • src/data/selectors.jsnew, computed analytics + a LIFECYCLE_STAGES/progress map.
  • Dashboards/components: OwnerSnapshot.jsx, Dashboard.jsx, leaderboard, OwnerProjectDetail.jsx (lifecycle/inspection/estimate UI + scope badge), LeadProjectPage.jsx (same surfaced for pipeline projects), KanbanCard.jsx (date anchor), SubcontractorTasksPage.jsx/TaskViewModal.jsx/SubcontractorTaskDetailPage.jsx (stage machine, On Hold, columns, richer modal).

Out of scope (YAGNI)

  • No backend/persistence (mock store only); uploads are session-only.
  • No Inspector login/role (external inspector stored as contact data).
  • No visual redesign beyond what these features require.

Build sequencing

  1. Canonical identity + resolvePerson.
  2. Financial coherence + missing breakdowns + variance signs.
  3. Feature-breaking fixes (leads seed, sub logins, task↔project).
  4. Ten threaded scenarios incl. discrepancy cases.
  5. Pipeline breadth + leaderboard.
  6. selectors.js + dashboard wiring.
  7. Project lifecycle state machine + progress %.
  8. Inspections (damage + final) + scope-variance badge + estimate versions.
  9. Subcontractor task stage machine + UI.
  10. Verify build + reconciliation spot-checks at each major step.

Verification

  • npm run build clean after each major step.
  • Reconciliation: dashboard revenue == Σ project contract values; pipeline total == Σ lead values; a threaded scenario navigable lead→project→task→invoice→commission with consistent names/dates; a discrepancy project shows reported vs verified + revised estimate versions.
  • Dev run: Leads page non-empty; each subcontractor login sees their tasks; no "Unknown" labels; project progress % matches lifecycle stage.

Open items (pending user input)

  • Stage-name tweaks: user chose "mostly good, I'll tweak a few" for both the project lifecycle and subcontractor stage names — specific renames TBD before implementation.