# 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 1–6), then the three interactive subsystems (Phases 7–9). --- ## 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 `e1`–`e5`; Sales/personnel `p1` (Jesus Gonzales), `p2` (Sarah Sales); Contractor `con_001`; Subcontractors `sub_001`–`sub_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 ~28–35 records in the page's shape; never show the empty state. - **Subcontractor access:** add login user records for `sub_002`–`sub_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 (§7–8). ## 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)* | 40–70% | | Work Complete — Awaiting Inspection | 80% | | Final Inspection (Scheduled → In Progress) | 85–90% | | 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 2–5) 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. ## 10. Profiles, skill catalog & AI dispatch context Every person (employee **and** subcontractor) gets a two-layer `profile`, surfaced through a self-service **User Details** page (all roles, including owners) and an owner-facing **Employee/Subcontractor Details** view. **① Self section** (person edits; owner can view): preferred name, photo, phone, alt contact, address, emergency contact; short bio, years of experience/since-date, languages; self-declared specialties + **equipment carried** (e.g., tarp, ladder rack, drone); availability/service areas. Subcontractors also: company name, license #, insurance/COI + expiry, W-9 status. **② Company section** (owner/admin edits; **private to owner/admin — not shown to the person**): company bio / internal notes ("reliable in storms, keeps a tarp on the truck"); internal status/tags (preferred / probation / do-not-use); **skill scores** (see below); pay/commission terms; hire date; manager. **③ Achievements & levels** (employees): read-only, pulled from ProCanvas gamification (level, XP, streak, badges, achievement tiers). **Skill catalog (shared, org-level):** `skillCatalog[]` = `{ id, name, description }` defined by the owner. Each person carries `skillScores[]` = `{ skillId, score: 0–100 | 'N/A' }`. Comparable across people; new skills added org-wide. **AI dispatch context (coherence with LynkDispatch):** `DISPATCH_REPS` map to canonical people; each rep's profile (equipment + skill scores + notes) is the structured context the dispatch engine references. The pre-authored `DISPATCH_RECOMMENDATIONS` (`factors.skillMatch`, `reasons[]`, `aiInsight`) are written to **cite real profile facts** (e.g., *"Carlos — 92 Emergency Tarp · carries tarp on truck"*), so "the AI read their profile" is demonstrably true on screen. **Pages/access:** - **User Details / My Profile** (`/me/profile` or similar) — every logged-in role edits their self-section + sees their achievements. - **Owner Employee/Subcontractor Details** — extends People/Vendor directories with a person detail view showing the full profile incl. company section + skill scores; owner edits company notes/scores and manages the skill catalog. --- ## 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. - Profiles/skills/equipment → attached to canonical people; surfaced on User Details + owner Employee Details; cited by LynkDispatch recommendations; subcontractor profile visible in their own login. ## 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.js` — **new**, 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. Profiles + skill catalog + User Details page + owner Employee Details + dispatch AI-context wiring. 11. 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.