JOB 868CA125 · REVISION 0
Split candidate names into first and last name fields
phantomtiger04@gmail.com
REQUEST
I want candidates to have separate First name and Last name fields instead of one Full name field. Please update the Add Candidate and Edit Candidate forms to use First name and Last name. Candidate lists and candidate profiles should continue displaying the person’s complete name. Migrate all existing candidates automatically. For existing names, use the first word as the first name and everything after it as the last name. If a candidate only has one word in their name, keep it as the first name and leave the last name empty. Candidate search must work with either the first name, last name, or complete name. Make sure existing candidate notes, assigned jobs, pipeline stages, email addresses, and other information are preserved. Please test that Ava Chen is migrated to: First name: Ava Last name: Chen Also verify that her existing notes, assigned job, and pipeline stage still work after the migration. Do not modify the production application or production database. Build this as an isolated preview.
APPROVED PLAN
1. User-visible behavior - Add/Edit Candidate forms use required First name and optional Last name fields. - Candidate lists, profiles, initials, and search display/use the complete name. - Search matches first name, last name, complete name, and existing candidate metadata. - Existing candidates are migrated automatically using: - First word → first name - Remaining words → last name - Single word → first name only - Ava Chen becomes First name `Ava`, Last name `Chen`; her note, assigned job, and `interview` stage remain intact. 2. Frontend changes - Update `Candidate`/`CandidateInput` types and fallback demo data. - Replace the form’s `Name` field with `First name` and `Last name`. - Add a shared complete-name formatter for lists, profiles, initials, and display. - Update client-side search to include first name, last name, complete name, title, company, and location. - Update Playwright selectors and workflow assertions. 3. Backend and Convex changes - Change API validation and Convex create/update mutations to accept `firstName` and `lastName`. - Store normalized trimmed names and preserve email, title, company, location, stage, and job assignment. - Replace `candidates.name` with `firstName` and optional `lastName` in the final schema. - Rebuild `searchText` from complete name plus existing searchable metadata. - Update dashboard serialization and fallback data. - Keep notes and job references keyed by stable external IDs. 4. Versioned migration Yes. This is a breaking stored-data change. - Bump the application/migration version from `0.1.0` to `0.2.0`, with exact `from: "0.1.0"`. - Add `.factory/schema.transition.ts` with a widened candidate shape accepting old `name` records and new first/last-name fields. - Extend the existing full application-table snapshot mechanism (`users`, `jobs`, `candidates`, `notes`) using `migrationBackupRows`. - Forward migration: - Parse each old `name` with the requested first-word rule. - Write `firstName`/`lastName`. - Remove the legacy `name` field. - Recompute `searchText`. - Remain idempotent on reapply. - Rollback restores the snapshot, including legacy names; regenerated Convex IDs and declared `jobId`/`candidateId` references are rewritten through the existing ID-map mechanism. - Validation must check row counts and invariants: candidate/job/note counts, stable external IDs, note ownership, job assignments, stages, email addresses, and complete transformed names. - The orchestrated preview lifecycle remains apply → validate → rollback → validate old data → reapply → validate final data, followed by deployment of the narrow final schema. 5. Tests and browser verification - Add migration unit coverage for multi-word and single-word names, idempotence, rollback, counts, and preserved relationships. - Update data tests for first/last-name create/update behavior and search. - Add explicit Ava assertions for: - `Ava` / `Chen` - existing Juniper Works job assignment - `interview` stage - existing note body and candidate association - Update the browser smoke test to create/edit candidates with separate fields and verify complete-name display and searches by first, last, and full name. - Run the configured typecheck, unit tests, build, isolated Convex migration lifecycle, and Playwright smoke test. 6. Risks or questions No safety blocker was found for an isolated preview. Production remains untouched if the factory uses its existing cloned-preview workflow and factory-only migration guards. Primary implementation risk is ensuring the transient schema is active during both rollback and reapply; the factory’s `prepare-migration` flow is designed for this and should be used.
BEWARE: your OS is not officially supported by Playwright; downloading fallback build for ubuntu24.04-x64. Downloading Chrome for Testing 151.0.7922.34 (playwright chromium v1234) from https://cdn.playwright.dev/builds/cft/151.0.7922.34/linux64/chrome-linux64.zip | | 0% of 184.3 MiB |■■■■■■■■ | 10% of 184.3 MiB |■■■■■■■■■■■■■■■■ | 20% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■ | 30% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 40% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 50% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 60% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 70% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 80% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 90% of 184.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 100% of 184.3 MiB Chrome for Testing 151.0.7922.34 (playwright chromium v1234) downloaded to /home/vercel-sandbox/.cache/ms-playwright/chromium-1234 BEWARE: your OS is not officially supported by Playwright; downloading fallback build for ubuntu24.04-x64. Downloading FFmpeg (playwright ffmpeg v1011) from https://cdn.playwright.dev/dbazure/download/playwright/builds/ffmpeg/1011/ffmpeg-linux.zip | | 0% of 2.3 MiB |■■■■■■■■ | 10% of 2.3 MiB |■■■■■■■■■■■■■■■■ | 20% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■ | 30% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 40% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 50% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 60% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 70% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 80% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 90% of 2.3 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 100% of 2.3 MiB FFmpeg (playwright ffmpeg v1011) downloaded to /home/vercel-sandbox/.cache/ms-playwright/ffmpeg-1011 BEWARE: your OS is not officially supported by Playwright; downloading fallback build for ubuntu24.04-x64. Downloading Chrome Headless Shell 151.0.7922.34 (playwright chromium-headless-shell v1234) from https://cdn.playwright.dev/builds/cft/151.0.7922.34/linux64/chrome-headless-shell-linux64.zip | | 0% of 114.7 MiB |■■■■■■■■ | 10% of 114.7 MiB |■■■■■■■■■■■■■■■■ | 20% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■ | 30% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 40% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 50% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 60% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 70% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 80% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 90% of 114.7 MiB |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 100% of 114.7 MiB Chrome Headless Shell 151.0.7922.34 (playwright chromium-headless-shell v1234) downloaded to /home/vercel-sandbox/.cache/ms-playwright/chromium_headless_shell-1234 Running 1 test using 1 worker ✘ 1 e2e/factory-preview.spec.ts:5:1 › reusable login and recruiting workflow work in the preview (7.6s) ✘ 2 e2e/factory-preview.spec.ts:5:1 › reusable login and recruiting workflow work in the preview (retry #1) (6.4s) 1) e2e/factory-preview.spec.ts:5:1 › reusable login and recruiting workflow work in the preview ── Error: expect(locator).toHaveValue(expected) failed Locator: getByLabel('Pipeline stage') Expected: "interview" Received: "offer" Timeout: 5000ms Call log: - Expect "toHaveValue" with timeout 5000ms - waiting for getByLabel('Pipeline stage') 14 × locator resolved to <select>…</select> - unexpected value "offer" 19 | await page.getByText("Ava Chen").click(); 20 | await expect(page.getByRole("heading", { name: "Ava Chen" })).toBeVisible(); > 21 | await expect(page.getByLabel("Pipeline stage")).toHaveValue("interview"); | ^ 22 | await expect(page.getByText("Strong product narrative. Customer interview scheduled for Thursday.")).toBeVisible(); 23 | await page.getByRole("button", { name: "×" }).click(); 24 | at /vercel/sandbox/target/e2e/factory-preview.spec.ts:21:51 attachment #1: screenshot (image/png) ────────────────────────────────────────────────────────── .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview/test-failed-1.png ──────────────────────────────────────────────────────────────────────────────────────────────── attachment #2: video (video/webm) ────────────────────────────────────────────────────────────── .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview/video.webm ──────────────────────────────────────────────────────────────────────────────────────────────── Error Context: .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview/error-context.md attachment #4: trace (application/zip) ───────────────────────────────────────────────────────── .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview/trace.zip Usage: npx playwright show-trace .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview/trace.zip ──────────────────────────────────────────────────────────────────────────────────────────────── Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── Error: expect(locator).toHaveValue(expected) failed Locator: getByLabel('Pipeline stage') Expected: "interview" Received: "offer" Timeout: 5000ms Call log: - Expect "toHaveValue" with timeout 5000ms - waiting for getByLabel('Pipeline stage') 14 × locator resolved to <select>…</select> - unexpected value "offer" 19 | await page.getByText("Ava Chen").click(); 20 | await expect(page.getByRole("heading", { name: "Ava Chen" })).toBeVisible(); > 21 | await expect(page.getByLabel("Pipeline stage")).toHaveValue("interview"); | ^ 22 | await expect(page.getByText("Strong product narrative. Customer interview scheduled for Thursday.")).toBeVisible(); 23 | await page.getByRole("button", { name: "×" }).click(); 24 | at /vercel/sandbox/target/e2e/factory-preview.spec.ts:21:51 attachment #1: screenshot (image/png) ────────────────────────────────────────────────────────── .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview-retry1/test-failed-1.png ──────────────────────────────────────────────────────────────────────────────────────────────── attachment #2: video (video/webm) ────────────────────────────────────────────────────────────── .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview-retry1/video.webm ──────────────────────────────────────────────────────────────────────────────────────────────── Error Context: .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview-retry1/error-context.md attachment #4: trace (application/zip) ───────────────────────────────────────────────────────── .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview-retry1/trace.zip Usage: npx playwright show-trace .factory/artifacts/playwright/factory-preview-reusable-l-2b6e5-orkflow-work-in-the-preview-retry1/trace.zip ──────────────────────────────────────────────────────────────────────────────────────────────── 1 failed e2e/factory-preview.spec.ts:5:1 › reusable login and recruiting workflow work in the preview ─── $ playwright test error: script "test:e2e" exited with code 1
TIMELINE
Request received
Isolated backend cloned; Codex implementation started
Running idempotent migration and validation
Running typecheck, tests, and production build
Committing branch and creating Vercel preview
Running deployed browser smoke tests and recording evidence
Implementation failed
1 evidence artifacts captured
log: 868ca125-701d-49d4-8dc5-5ef6d453f0ae/failure.log ↗