Files
jobtrackingapp/docs/operations/job-opportunity-cutover.md
cesnimda 955182b7c2
CI and Deploy / test (pull_request) Failing after 1m22s
CI and Deploy / deploy (pull_request) Has been skipped
fix: close release preflight gaps
Route public health checks to the API, backfill and synchronize job opportunities, stabilize SPA smoke tests, and document operator-only production steps.
2026-07-31 20:18:30 +02:00

1.8 KiB

Job opportunity cutover

The release-readiness build closes the write-side gap:

  • normal application creation and Gmail suggested-job creation both create a linked Job;
  • edits synchronize opportunity fields through JobOpportunitySync;
  • startup idempotently creates one Job for every legacy JobApplication whose JobId is null.

The startup backfill is additive and runs after the deployment backup. It does not drop or overwrite legacy application columns.

Production validation

Run these read-only checks after deployment. Expected result for every count is 0:

SELECT COUNT(*) AS missing_job
FROM JobApplications
WHERE JobId IS NULL;

SELECT COUNT(*) AS missing_target
FROM JobApplications a
LEFT JOIN Jobs j ON j.Id = a.JobId
WHERE a.JobId IS NOT NULL AND j.Id IS NULL;

SELECT COUNT(*) AS owner_mismatch
FROM JobApplications a
JOIN Jobs j ON j.Id = a.JobId
WHERE NOT (a.OwnerUserId <=> j.OwnerUserId);

SELECT COUNT(*) AS field_mismatch
FROM JobApplications a
JOIN Jobs j ON j.Id = a.JobId
WHERE NOT (a.CompanyId <=> j.CompanyId)
   OR NOT (a.JobTitle <=> j.JobTitle)
   OR NOT (a.Location <=> j.Location)
   OR NOT (a.JobUrl <=> j.JobUrl)
   OR NOT (a.Description <=> j.Description)
   OR NOT (a.Salary <=> j.Salary);

<=> is MariaDB/MySQL's null-safe equality operator. Do not use these statements as an update script.

Expand/contract release order

  1. Deploy the additive backfill and synchronized writers.
  2. Capture the validation counts above and observe one release.
  3. Change reads to use Job; keep compatibility columns during that release.
  4. Re-run validation against a fresh backup restore.
  5. Only then make JobId required and drop duplicated opportunity columns in a later migration.

Do not combine the destructive column drop with the first production backfill.