Exercise 1: Rolling Back Mid-Migration — Possible Solution ============================================================ What happens when Release 2's code is replaced by Release 1's: - The schema stays as it is. Rolling back code doesn't roll back migrations, and it doesn't need to: Release 1 is where the status column was added, so Release 1's code already runs happily against it (it ignores the column). - Posts archived under Release 2 have status = 'ARCHIVED' and published = false. Release 1's code only reads published, so it treats them as drafts: hidden from the front page AND no longer reachable by link. Editors see them as drafts. - Any post created or edited while Release 1's code is back runs WITHOUT dual writing: status stays NULL on new posts, and on edited posts published changes while status keeps its old value. The two fields can now disagree. Nothing is lost: the archived state is still stored in status. But the data is no longer guaranteed consistent. Before redeploying Release 2 (fixed): 1. Find rows that drifted while the old code ran: SELECT "id", "status", "published" FROM "Post" WHERE "status" IS NULL OR ("status" = 'PUBLISHED') <> "published"; (This is Release 3's own check. ARCHIVED + false counts as consistent, because ('ARCHIVED' = 'PUBLISHED') is false, matching published = false.) 2. Decide which field is right for each case. For rows edited under the old code, published is the most recent truth, so re-derive: status = PUBLISHED if published, otherwise keep ARCHIVED if it was archived, else DRAFT. 3. Run the backfill again (Release 3's SQL is re-runnable), then check the mismatch count is 0. 4. Tell editors that archived posts looked like drafts during the rollback, in case anyone "republished" one by mistake. WHY THIS WORKS AS AN ANSWER ------------------------------ It separates what a code rollback does (only the code changes) from what it can't do (undo data written in the meantime), and shows that expand and contract keeps rollback safe: no error, no data loss, just temporary inconsistency that the existing backfill and check can repair. The mismatch query is the same one Release 3 already uses.