docs: add Texan roster (real names + LUP employee ids), login person picker, optional profile identity fields; update plan + protocol order
This commit is contained in:
@@ -14,25 +14,34 @@
|
||||
|
||||
---
|
||||
|
||||
## Canonical ID reference (used throughout)
|
||||
## Canonical roster (single source of truth — used throughout)
|
||||
|
||||
The canonical scheme is the `MOCK_USERS` one. Remap everything else to it:
|
||||
Canonical id scheme = `MOCK_USERS`. Real Texan names. Unified `LUP-####` empIds. Shared password `password`.
|
||||
|
||||
| Entity | Canonical id | Name | Old ids to replace |
|
||||
|--------|-------------|------|--------------------|
|
||||
| Owner 1 | `own_001` | Justin Johnson | `owner_001` |
|
||||
| Owner 2 | `own_002` | Diana Reeves | `owner_002`, and name "Maria Garcia" |
|
||||
| Admin 1 | `a1` | Adam Admin | `ADM01`, name "Admin One" |
|
||||
| Admin 2 | `a2` | Amanda Manager | `ADM02`, name "Admin Two" |
|
||||
| Admin 3 | `a3` | Arthur Director | `ADM03`, name "Admin Three" |
|
||||
| Field agent 1 | `e1` | Frank Agent | `FA001` |
|
||||
| Field agent 2 | `e2` | Fiona Field | `FA002` |
|
||||
| Field agent 3 | `e3` | Fred Flyer | `FA003` |
|
||||
| Field agent 4 | `e4` | Felicity Fast | `FA004` |
|
||||
| Field agent 5 | `e5` | Felix Fixer | `FA005` |
|
||||
| Justin email | — | `justin@lynkeduppro.com` | `justin@johnsondev.com` (reconcile to one — use lynkeduppro.com everywhere) |
|
||||
| id | Role | Name | empId | Login type | Login id | Old id(s) | Old name |
|
||||
|----|------|------|-------|-----------|----------|-----------|----------|
|
||||
| own_001 | OWNER | Justin Johnson | LUP-1001 | owner | justin | `owner_001` | — (email → `justin@lynkeduppro.com`) |
|
||||
| own_002 | OWNER | Diana Reeves | LUP-1002 | owner | diana | `owner_002` | "Maria Garcia" |
|
||||
| a1 | ADMIN | Wade Hollis | LUP-1010 | employee | LUP-1010 | `ADM01` | "Adam Admin" / "Admin One" |
|
||||
| a2 | ADMIN | Darlene Brooks | LUP-1011 | employee | LUP-1011 | `ADM02` | "Amanda Manager" / "Admin Two" |
|
||||
| a3 | ADMIN | Roy Schaefer | LUP-1012 | employee | LUP-1012 | `ADM03` | "Arthur Director" / "Admin Three" |
|
||||
| p1 | SALES_REP | Jesus Gonzales | LUP-1030 | employee | LUP-1030 | — | — (keep) |
|
||||
| p2 | SALES_REP | Sarah Calloway | LUP-1031 | employee | LUP-1031 | — | "Sarah Sales" |
|
||||
| e1 | FIELD_AGENT | Cody Tatum | LUP-1040 | employee | LUP-1040 | `FA001` | "Frank Agent" |
|
||||
| e2 | FIELD_AGENT | Hannah Reyes | LUP-1041 | employee | LUP-1041 | `FA002` | "Fiona Field" |
|
||||
| e3 | FIELD_AGENT | Travis Boone | LUP-1042 | employee | LUP-1042 | `FA003` | "Fred Flyer" |
|
||||
| e4 | FIELD_AGENT | Shelby Greer | LUP-1043 | employee | LUP-1043 | `FA004` | "Felicity Fast" |
|
||||
| e5 | FIELD_AGENT | Dalton Pruitt | LUP-1044 | employee | LUP-1044 | `FA005` | "Felix Fixer" |
|
||||
| con_001 | CONTRACTOR | Mike Brennan | LUP-3001 | contractor | mike | — | "Mike Contractor" |
|
||||
| sub_001 | SUBCONTRACTOR | Carlos Mendoza | LUP-2001 | subcontractor | carlos | — | "Carlos Subcontractor" |
|
||||
| sub_002 | SUBCONTRACTOR | Maya Patel | LUP-2002 | subcontractor | maya | — | (keep) |
|
||||
| sub_003 | SUBCONTRACTOR | Dwayne Boudreaux | LUP-2003 | subcontractor | dwayne | — | (current sub_003 name) |
|
||||
| sub_004 | SUBCONTRACTOR | Jennifer Castillo | LUP-2004 | subcontractor | jennifer | — | (current sub_004 name) |
|
||||
| sub_005 | SUBCONTRACTOR | Greg Alston | LUP-2005 | subcontractor | greg | — | (keep) |
|
||||
|
||||
Org role taxonomy (`orgMembers[].roleKey`: OWNER/ADMIN/SALES_REP/CANVASSER/SUBCONTRACTOR) stays as-is; only the `userId` it points to changes.
|
||||
Org role taxonomy (`orgMembers[].roleKey`) stays; only the `userId` it points to changes. Email rule: use `@lynkeduppro.com` consistently.
|
||||
|
||||
**Execution order** (overrides plain numeric order; see execution protocol): 1 → 2 → **R (roster rename, below)** → 3 → 4 → 5 → 6 → 7 → 8 → 9 → **L (login picker, below)**.
|
||||
|
||||
---
|
||||
|
||||
@@ -219,7 +228,7 @@ git commit -m "fix(data): seed leads list so the Leads page is populated on load
|
||||
**Files:**
|
||||
- Modify: `src/data/mockStore.jsx` — `MOCK_USERS`.
|
||||
|
||||
- [ ] **Step 1: Add four login user records** to `MOCK_USERS` for `sub_002`–`sub_005`, mirroring the `sub_001` (Carlos) record shape (`id`, `name`, `email`, `password: 'password'`, `role: 'SUBCONTRACTOR'`, type `subcontractor`). Use the names already in `MOCK_SUBCONTRACTORS` (Maya Patel, Dwayne …, Jennifer …, Greg Alston) so ids and names match across collections.
|
||||
- [ ] **Step 1: Add four login user records** to `MOCK_USERS` for `sub_002`–`sub_005`, mirroring the `sub_001` (Carlos Mendoza) record shape (`id`, `name`, `email`, `empId`, `password: 'password'`, `role: 'SUBCONTRACTOR'`, type `subcontractor`). Use the **canonical roster** names + empIds (Maya Patel/LUP-2002, Dwayne Boudreaux/LUP-2003, Jennifer Castillo/LUP-2004, Greg Alston/LUP-2005) and usernames (maya/dwayne/jennifer/greg) so ids/names match across collections and the login picker works.
|
||||
- [ ] **Step 2: Verify in dev.** Log in as `sub_002`'s email / `password`. Expected: the subcontractor dashboard loads and shows that sub's tasks/notifications (Maya's rich set is now reachable).
|
||||
- [ ] **Step 3: Verify build.** Run: `npm run build` — Expected: `✓ built`.
|
||||
- [ ] **Step 4: Commit.**
|
||||
@@ -270,10 +279,89 @@ git commit -m "feat(data): add lead values, fix Complete-stage data, populate st
|
||||
|
||||
---
|
||||
|
||||
## Task R: Canonical roster rename (real Texan names + LUP empIds)
|
||||
|
||||
**Runs after Task 2, before Task 3.** **Files:** `src/data/mockStore.jsx` (people source records) + repo-wide name-string replacement.
|
||||
|
||||
- [ ] **Step 1: Set names + empIds on source records.** In `MOCK_USERS`, `MOCK_PERSONNEL`/`personnel`, `MOCK_OWNERS`, and `MOCK_SUBCONTRACTORS`, for each person in the Canonical Roster set the `name` to the roster name and set `empId` to the roster `LUP-####`. Reconcile Justin's email to `justin@lynkeduppro.com`. Keep password `password`.
|
||||
- [ ] **Step 2: Repo-wide name replace.** Replace every occurrence of each old name string with its new name across the whole repo (covers denormalized copies in teamMembers, subcontractor tasks, kanban activity, `DISPATCH_REPS`, and any component). Pairs:
|
||||
- "Frank Agent"→"Cody Tatum", "Fiona Field"→"Hannah Reyes", "Fred Flyer"→"Travis Boone", "Felicity Fast"→"Shelby Greer", "Felix Fixer"→"Dalton Pruitt"
|
||||
- "Adam Admin"→"Wade Hollis", "Amanda Manager"→"Darlene Brooks", "Arthur Director"→"Roy Schaefer"
|
||||
- "Admin One"→"Wade Hollis", "Admin Two"→"Darlene Brooks", "Admin Three"→"Roy Schaefer"
|
||||
- "Maria Garcia"→"Diana Reeves", "Sarah Sales"→"Sarah Calloway"
|
||||
- "Carlos Subcontractor"→"Carlos Mendoza", "Mike Contractor"→"Mike Brennan"
|
||||
- sub_003 current name → "Dwayne Boudreaux", sub_004 current name → "Jennifer Castillo" (look up the current strings first via `git grep`).
|
||||
- [ ] **Step 3: Verify old names gone.** Run:
|
||||
|
||||
```bash
|
||||
git grep -nE "Frank Agent|Fiona Field|Fred Flyer|Felicity Fast|Felix Fixer|Adam Admin|Amanda Manager|Arthur Director|Admin (One|Two|Three)|Maria Garcia|Sarah Sales|Carlos Subcontractor|Mike Contractor" -- src
|
||||
```
|
||||
|
||||
Expected: **no matches**.
|
||||
|
||||
- [ ] **Step 4: Verify build.** Run: `npm run build` — Expected: `✓ built`.
|
||||
- [ ] **Step 5: Commit.**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "feat(data): canonical roster — real Texan names + unified LUP-#### employee ids"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task L: Login per-role person picker
|
||||
|
||||
**Runs last.** **Files:** `src/pages/Login.jsx`; `src/context/AuthContext.jsx` (only if id matching needs updating).
|
||||
|
||||
- [ ] **Step 1: Inline demo-account list** in `Login.jsx` (keeps this task's lane to Login.jsx). Define from the roster:
|
||||
|
||||
```jsx
|
||||
const DEMO_ACCOUNTS = {
|
||||
customer: [{ name: 'Alice Carter', loginType: 'customer', id: 'alice', pw: 'password' }],
|
||||
employee: [
|
||||
{ name: 'Wade Hollis (Admin)', loginType: 'employee', id: 'LUP-1010', pw: 'password' },
|
||||
{ name: 'Darlene Brooks (Admin)',loginType: 'employee', id: 'LUP-1011', pw: 'password' },
|
||||
{ name: 'Roy Schaefer (Admin)', loginType: 'employee', id: 'LUP-1012', pw: 'password' },
|
||||
{ name: 'Cody Tatum (Agent)', loginType: 'employee', id: 'LUP-1040', pw: 'password' },
|
||||
{ name: 'Hannah Reyes (Agent)', loginType: 'employee', id: 'LUP-1041', pw: 'password' },
|
||||
{ name: 'Travis Boone (Agent)', loginType: 'employee', id: 'LUP-1042', pw: 'password' },
|
||||
{ name: 'Shelby Greer (Agent)', loginType: 'employee', id: 'LUP-1043', pw: 'password' },
|
||||
{ name: 'Dalton Pruitt (Agent)', loginType: 'employee', id: 'LUP-1044', pw: 'password' },
|
||||
],
|
||||
owner: [
|
||||
{ name: 'Justin Johnson', loginType: 'owner', id: 'justin', pw: 'password' },
|
||||
{ name: 'Diana Reeves', loginType: 'owner', id: 'diana', pw: 'password' },
|
||||
],
|
||||
contractor: [{ name: 'Mike Brennan', loginType: 'contractor', id: 'mike', pw: 'password' }],
|
||||
subcontractor: [
|
||||
{ name: 'Carlos Mendoza', loginType: 'subcontractor', id: 'carlos', pw: 'password' },
|
||||
{ name: 'Maya Patel', loginType: 'subcontractor', id: 'maya', pw: 'password' },
|
||||
{ name: 'Dwayne Boudreaux', loginType: 'subcontractor', id: 'dwayne', pw: 'password' },
|
||||
{ name: 'Jennifer Castillo',loginType: 'subcontractor', id: 'jennifer', pw: 'password' },
|
||||
{ name: 'Greg Alston', loginType: 'subcontractor', id: 'greg', pw: 'password' },
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Replace the quick-access row** so each role chip, when clicked, expands the list of people for that role; clicking a person calls a `pickDemo(acct)` that sets `loginType`, `identifier`, `password` (and may submit). Single-person roles act as one-click.
|
||||
- [ ] **Step 3: Ensure AuthContext accepts the ids.** Confirm `login(identifier, password, loginType)` matches employees by `empId` (`LUP-####`) and owner/contractor/sub by username. If `MOCK_USERS` records carry the LUP `empId` (set in Task R / Task 7), update the match in `AuthContext.jsx` only if needed.
|
||||
- [ ] **Step 4: Verify in dev.** Log in via the picker as an Admin (LUP-1010), an Agent (LUP-1041), the second Owner (Diana), and a Subcontractor (Maya). Each lands on the right dashboard.
|
||||
- [ ] **Step 5: Verify build.** Run: `npm run build` — Expected: `✓ built`.
|
||||
- [ ] **Step 6: Commit.**
|
||||
|
||||
```bash
|
||||
git add src/pages/Login.jsx src/context/AuthContext.jsx
|
||||
git commit -m "feat(login): per-role person picker for quick demo access"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Self-review checklist (run after all tasks)
|
||||
|
||||
- [ ] `git grep -nE "owner_00[12]|\bADM0[123]\b|FA00[12345]"` returns **no matches** in `src/data/mockStore.jsx`.
|
||||
- [ ] All old placeholder names gone (the Task R Step 3 grep → no matches); roster names appear in projects/tables/schedule/dispatch/leaderboard.
|
||||
- [ ] `own_002` is "Diana Reeves" everywhere (`git grep -n "Maria Garcia"` → no matches).
|
||||
- [ ] Login picker: signing in as an Admin (LUP-1010), Agent (LUP-1041), Owner #2 (Diana), and a Sub (Maya) each lands on the correct dashboard.
|
||||
- [ ] Every project with a `budgetBreakdown` reconciles (column sums == totals).
|
||||
- [ ] `npm run build` is clean.
|
||||
- [ ] Dev run: Leads page non-empty; each `sub_00N` login sees its own tasks; On-Hold styled; no "Unknown" person labels on subcontractor tasks.
|
||||
|
||||
@@ -47,6 +47,7 @@ Execution order is the task number. Each task's editable surface:
|
||||
|---|------|---------------|--------------------|
|
||||
| 1 | DEMO_TODAY anchor | `mockStore.jsx` (top-of-file constant) + `KanbanCard.jsx:~14` | — |
|
||||
| 2 | `resolvePerson` selector | `mockStore.jsx` (provider body: people index + context `value` object) | — |
|
||||
| **R** | **Canonical roster rename** (real Texan names + LUP empIds) | `mockStore.jsx` people source records (`MOCK_USERS`/personnel/owners/subcontractors) **+ repo-wide replacement of the old name strings** | ⚠ cross-cutting (touches many regions/files) — runs **after Task 2, before Task 3**, alone, then commits |
|
||||
| 3 | Remap `orgMembers` | `mockStore.jsx` → the `orgMembers` useState array only | — |
|
||||
| 4 | Remap sub-task actor ids | `mockStore.jsx` → `MOCK_SUBCONTRACTOR_TASKS` + `MOCK_NOTIFICATIONS` (actor/sender id + denormalized name fields only) | ⚠ shares `MOCK_SUBCONTRACTOR_TASKS` with Task 8 — must run before Task 8 |
|
||||
| 5 | Financial reconciliation + breakdowns | `mockStore.jsx` → the `projects` array only | — |
|
||||
@@ -54,10 +55,13 @@ Execution order is the task number. Each task's editable surface:
|
||||
| 7 | Sub logins | `mockStore.jsx` → `MOCK_USERS` only | — |
|
||||
| 8 | Task↔project + On Hold | `mockStore.jsx` → `MOCK_SUBCONTRACTOR_TASKS` (`projectId`/`location` only) + `SubcontractorTasksPage.jsx` + `TaskViewModal.jsx` | ⚠ shares array with Task 4 — runs after Task 4 |
|
||||
| 9 | Kanban values + Complete fixes | `mockStore.jsx` → `KANBAN_LEADS_INITIAL` + `KANBAN_PROJECT_DATA` only | — |
|
||||
| **L** | **Login per-role person picker** | `src/pages/Login.jsx` + `src/context/AuthContext.jsx` only | runs **last** |
|
||||
|
||||
**Canonical execution order:** 1 → 2 → **R** → 3 → 4 → 5 → 6 → 7 → 8 → 9 → **L**. (Task R establishes names before the id-remaps; Task L wires the picker after all people exist.)
|
||||
|
||||
**Lane rule:** if an implementer believes it must touch a surface outside its lane, it STOPS and reports `NEEDS_CONTEXT` to the controller — it does not edit out of lane.
|
||||
|
||||
**Invariant every task must preserve:** the canonical ID scheme from the plan (`own_001/own_002`, `e1–e5`, `a1–a3`, `con_001`, `sub_001–005`). No task may reintroduce `owner_001`/`FA0*`/`ADM0*` ids or the names "Maria Garcia"/"Admin One/Two/Three".
|
||||
**Invariant every task must preserve:** the canonical ID scheme (`own_001/own_002`, `e1–e5`, `a1–a3`, `con_001`, `sub_001–005`) **and the canonical roster names/empIds** (see the plan's roster table — Wade Hollis, Cody Tatum, Carlos Mendoza, etc., with `LUP-####` empIds). After Task R, no task may reintroduce old ids (`owner_001`/`FA0*`/`ADM0*`) **or** old placeholder names ("Frank Agent", "Adam Admin", "Admin One/Two/Three", "Maria Garcia", "Sarah Sales", "Carlos Subcontractor", "Mike Contractor", etc.).
|
||||
|
||||
---
|
||||
|
||||
@@ -72,7 +76,7 @@ Execution order is the task number. Each task's editable surface:
|
||||
7. **Code-quality review** (fresh read-only subagent) — only after spec ✅: review the diff for correctness/quality. Issues → implementer fixes → re-review until ✅.
|
||||
8. **Mark task complete** in TodoWrite. Go to next task.
|
||||
|
||||
**Continuous execution:** the controller runs tasks 1→9 back-to-back without pausing to ask the human "should I continue?". Stop only on an unresolvable BLOCKED, genuine ambiguity, or all-tasks-complete.
|
||||
**Continuous execution:** the controller runs the canonical order (1 → 2 → R → 3 → 4 → 5 → 6 → 7 → 8 → 9 → L) back-to-back without pausing to ask the human "should I continue?". Stop only on an unresolvable BLOCKED, genuine ambiguity, or all-tasks-complete.
|
||||
|
||||
---
|
||||
|
||||
@@ -100,9 +104,9 @@ Final gate after Task 9: run the plan's **self-review checklist**, then a whole-
|
||||
- [ ] Only one implementer in flight at any time.
|
||||
- [ ] Tree clean before each dispatch.
|
||||
- [ ] Each task committed before the next starts.
|
||||
- [ ] Task 4 ran before Task 8 (shared array).
|
||||
- [ ] Task 4 ran before Task 8 (shared array); Task R ran after Task 2 and before Task 3.
|
||||
- [ ] No agent edited outside its §3 lane.
|
||||
- [ ] Canonical-ID invariant intact after every task.
|
||||
- [ ] Canonical-ID **and roster-name** invariant intact after every task (no old ids/names reintroduced).
|
||||
- [ ] Build green after every task.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user