TEFactory Control RoomISOLATED PREVIEWS
← All jobs

JOB E54FF9FB · REVISION 0

Split candidate names into first and last names

phantomtiger04@gmail.com

succeeded

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.

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

received

Request received

planning

Read-only planning run queued

awaiting approval

Plan sent; waiting for email approval

provisioning

Approved by email; provisioning queued

implementing

Isolated backend cloned; Codex implementation started

migrating

Running idempotent migration and validation

testing

Running typecheck, tests, and production build

deploying

Committing branch and creating Vercel preview

verifying

Running deployed browser smoke tests and recording evidence

succeeded

Preview verified and result email sent