JOB E54FF9FB · REVISION 0
Split candidate names into first and last names
phantomtiger04@gmail.com
REQUEST
Replace the single candidate “name” field with separate “firstName” and “lastName” fields throughout the application. This must be implemented as a versioned breaking migration: - Back up all application tables before transforming anything. - For each existing candidate, trim the current name. Store the last whitespace-separated word as lastName and everything before it as firstName. - For a one-word name, store it as firstName and use an empty lastName. - The final Convex schema must remove the old name field. - Update candidate creation, editing, searching, lists, avatars, and the candidate detail drawer. - Display the full name by joining firstName and lastName without extra spaces. - Preserve all external IDs, candidate-to-job relationships, notes, login data, and unrelated UI. - Add forward migration, rollback, rollback validation, reapply, and final validation. - Validate that candidate, job, note, and user counts remain unchanged. Show the migrated names in the preview and include automated tests for normal, multi-word, and one-word names.
APPROVED PLAN
1. User-visible behavior - Candidate forms will use separate First name and Last name fields; last name may be blank. - Candidate tables, search, avatars, and the detail drawer will display `firstName` + `lastName` joined with a single space only when both exist. - Existing candidates such as “Ava Chen” display unchanged; a one-word candidate displays that word without a trailing space. 2. Frontend changes - Update `Candidate`/`CandidateInput`, fallback demo records, and create/edit form state to use `firstName` and `lastName`. - Replace all candidate-name rendering/search/initials usages in `components/recruiting-app.tsx` with a small full-name helper. - Keep existing layout, controls, CSS hooks, and all `data-factory-stable` markers intact. - Update the candidate API Zod schema: required nonblank first name, optional/blank-permitted last name. 3. Backend and Convex changes - Change candidate creation and update mutation arguments, cleanup, return data, and `searchText` generation to use both name parts. - Update the Convex candidate schema to require `firstName` and `lastName` and remove `name`. - Update seed and fallback data so an empty preview displays the new fields. - Preserve candidate external IDs, `jobId`, note `candidateId`, jobs, users, login, and existing CRUD/stage behaviors. 4. Versioned breaking migration - Bump the app/migration version from `0.1.0` to `0.2.0`; append one ordered migration entry with exact `from: "0.1.0"` describing add `firstName`/`lastName`, transform names, and remove `name`. - Add `.factory/schema.transition.ts` where candidate `name`, `firstName`, and `lastName` are all optional, allowing both source records and rollback-restored records during the preview lifecycle. Keep `convex/schema.ts` as the final narrow schema. - Retain the full application-table snapshot: users, jobs, candidates, notes, including the existing jobs→candidates and candidates→notes relationship declarations. - Forward migration: trim legacy `name`, split on whitespace, assign the final word to `lastName` and preceding words to `firstName`; for one word, use an empty `lastName`; rebuild `searchText`; remove `name`. - Rollback: restore the complete backup documents, regenerate Convex IDs as the harness requires, rewrite declared references, and return to legacy candidate records containing `name`. - Reapply: reuse the existing migration hop/backup and run the transform again after rollback. - Final and rollback validation will explicitly verify unchanged counts for users, jobs, candidates, and notes. Final validation will also verify no candidate retains `name`, both new fields are strings, each split matches the legacy backed-up name, and `searchText` is correct. Rollback validation will compare restored records with the snapshot and assert the same counts. 5. Tests and browser verification - Update fallback CRUD tests for the new payload. - Add focused automated split/transform tests for: - normal: `Ava Chen` → `Ava` / `Chen` - multi-word: `Mary Jane Watson` → `Mary Jane` / `Watson` - one-word: `Madonna` → `Madonna` / `""` - Add/extend browser coverage (the configured `e2e/` directory is currently absent) to log in, confirm migrated candidate rows/drawer/avatar, search by first and last name, create/edit a one-word candidate, and confirm notes/job associations remain available. - Run the configured typecheck, tests, build, isolated migration lifecycle, visual capture/compare, and smoke checks. 6. Risks / questions This is safe to implement only through the repository’s isolated `factory-*` preview lifecycle; no source or production migration should be run directly. The request does not define whitespace-only legacy names. The migration should either map them to two empty strings and report them in validation, or fail validation for manual cleanup. I recommend reporting them explicitly while preserving the record; normal API creation will continue to require a real first name.
TIMELINE
Request received
Read-only planning run queued
Plan sent; waiting for email approval
Approved by email; provisioning queued
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
Preview verified and result email sent