955182b7c2
Route public health checks to the API, backfill and synchronize job opportunities, stabilize SPA smoke tests, and document operator-only production steps.
53 lines
1.8 KiB
Markdown
53 lines
1.8 KiB
Markdown
# 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`:
|
|
|
|
```sql
|
|
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.
|