max / makenotwork
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+42 insertions,
-0 deletions
| @@ -1,0 +1,42 @@ | |||
| 1 | + | -- Clear legacy covers that no URL rebuild can repair (audit problem b2046f13, | |
| 2 | + | -- observed in prod 2026-07-29). | |
| 3 | + | -- | |
| 4 | + | -- Migration 152 backfilled `cover_s3_key` by stripping scheme and host off | |
| 5 | + | -- `cover_image_url`, on the premise that a stored cover URL is always the | |
| 6 | + | -- canonical `{cdn_base}/{s3_key}` that `build_project_image_url` composes. Rows | |
| 7 | + | -- written before CDN_BASE_URL became required config held a path-style presigned | |
| 8 | + | -- URL instead (`{endpoint}/{bucket}/{key}?X-Amz-...`), so the strip kept the | |
| 9 | + | -- bucket segment and produced keys shaped | |
| 10 | + | -- `makenotwork-files/projects/<id>/image/<file>.png`. | |
| 11 | + | -- | |
| 12 | + | -- Both halves of such a row are dead. The URL is a 24-hour presigned link that | |
| 13 | + | -- expired the day after it was written, and rebuilding it against the now-correct | |
| 14 | + | -- CDN base still 404s: cdn.makenot.work fronts the public bucket, so a | |
| 15 | + | -- bucket-prefixed key resolves to `makenotwork-public/makenotwork-files/...`. | |
| 16 | + | -- The objects were never promoted to the public bucket under either spelling, so | |
| 17 | + | -- there is no key that serves them. Clearing the row renders no cover instead of | |
| 18 | + | -- a broken image; the owner re-uploads through the normal presign/confirm path, | |
| 19 | + | -- which mints a staging key, scans it, and writes a canonical URL. | |
| 20 | + | -- | |
| 21 | + | -- Scoped by shape rather than by id. A presigned URL in a durable column is the | |
| 22 | + | -- exact artifact, and no current writer can produce one: the only writers of | |
| 23 | + | -- these columns are `build_project_image_url` and the scan worker's promote, | |
| 24 | + | -- which both compose `{cdn_base}/{key}`. `cover_scan_status` returns to | |
| 25 | + | -- 'pending', the no-cover value from migration 162, so a future upload re-enters | |
| 26 | + | -- the scan gate. The size columns are deliberately untouched: they are NULL on | |
| 27 | + | -- the affected prod rows, so nothing was ever counted against storage, and a | |
| 28 | + | -- migration is the wrong place to move a storage counter. | |
| 29 | + | ||
| 30 | + | UPDATE projects | |
| 31 | + | SET cover_image_url = NULL, | |
| 32 | + | cover_s3_key = NULL, | |
| 33 | + | cover_scan_status = 'pending' | |
| 34 | + | WHERE cover_image_url LIKE '%X-Amz-Signature=%'; | |
| 35 | + | ||
| 36 | + | -- Migration 152 backfilled items the same way, so the same artifact is possible | |
| 37 | + | -- there. No prod row matches today; this keeps the two tables from drifting. | |
| 38 | + | UPDATE items | |
| 39 | + | SET cover_image_url = NULL, | |
| 40 | + | cover_s3_key = NULL, | |
| 41 | + | cover_scan_status = 'pending' | |
| 42 | + | WHERE cover_image_url LIKE '%X-Amz-Signature=%'; |