This commit is contained in:
2026-08-31 19:00:35 +05:30
parent d8cfe2e87b
commit ae6162a632

39
main.go
View File

@@ -87,10 +87,39 @@ func main() {
// one row out of 6,755. A separate column is untouched by that, and "when // one row out of 6,755. A separate column is untouched by that, and "when
// was this published" is worth knowing regardless. // was this published" is worth knowing regardless.
// //
// The backfill is not optional and must land in the same deploy. Membership // The backfill is not optional and must land in the same deploy as the
// of a store catalogue is currently the *existence* of the row, so switching // column. Membership of a store catalogue was the *existence* of the row,
// the read to `publishedat IS NOT NULL` without this empties every shop on // so reading `publishedat IS NOT NULL` without it empties every shop on the
// the platform at once. // platform at once.
//
// The backfill runs ONCE — only on the boot that adds the column.
//
// It used to run on every boot, and that quietly cancelled the whole point
// of the column. `WHERE publishedat IS NULL` matches a legacy row on the
// first boot and, on every boot after, matches exactly the products
// somebody is deliberately holding back: imported, not yet priced, waiting
// for review. A restart published all of them and backdated the release to
// the row's `created`, so it did not even look recent.
//
// Observed 2026-08-31: seventeen products imported at R mart at 15:55 sat
// correctly unpublished, and the next deploy published all seventeen
// stamped 15:55. With several deploys a day, the admin-catalogue tier could
// not survive an afternoon.
//
// Detecting "the column was just added" rather than tracking a migration
// version: the question is answerable from the schema itself, so it needs
// no new table and cannot drift out of step with one.
var hadPublishedAt int64
if err := db.DB.Raw(`
SELECT COUNT(1) FROM information_schema.columns
WHERE table_name = 'productlocations' AND column_name = 'publishedat'`).
Scan(&hadPublishedAt).Error; err != nil {
log.Fatal("could not check productlocations.publishedat:", err)
}
if hadPublishedAt == 0 {
// First boot with the column. Every existing row predates publication
// as a concept, and membership of this table WAS publication — so
// leaving them null would empty every shop on the platform at once.
if err := db.DB.Exec( if err := db.DB.Exec(
`ALTER TABLE productlocations ADD COLUMN IF NOT EXISTS publishedat timestamp`).Error; err != nil { `ALTER TABLE productlocations ADD COLUMN IF NOT EXISTS publishedat timestamp`).Error; err != nil {
log.Fatal("could not add productlocations.publishedat:", err) log.Fatal("could not add productlocations.publishedat:", err)
@@ -101,6 +130,8 @@ func main() {
WHERE publishedat IS NULL`).Error; err != nil { WHERE publishedat IS NULL`).Error; err != nil {
log.Fatal("could not backfill productlocations.publishedat:", err) log.Fatal("could not backfill productlocations.publishedat:", err)
} }
log.Println("productlocations.publishedat added and backfilled (one time)")
}
// The catalogue's own stable key for an imported product. // The catalogue's own stable key for an imported product.
// //