4 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 5 15042ccc76 a gallery is a carousel
It always rendered as one — data-carousel, a snap track, two arrows, driven by
carousel.client.js. The entity was the last thing still calling it something
else, and that collided with the site's own Gallery section: two nav rows
reading Gallery and Galleries, meaning a list of objects and a list of
photograph sets.

GalleriesPanel, GalleryPicker and GalleryItems become Carousels*, the endpoint
becomes /fofos-admin/carousels, the block kind becomes carousel and
subject-gallery becomes subject-carousel. The publish allowlist follows the
renamed tables.

What did NOT move: GALLERY_CONFIG at /fofos-admin/gallery, subjects.ts's
base '/gallery', and home_gallery_media. Those are the Gallery section and the
legacy rows, and both are correct.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 18:01:15 +01:00
pastilhasandClaude Opus 5 a67e3d741d publish the pages, the sections and the components
They were never in CONTENT_TABLES, so publish copied every table it knew about and none of the page
builder's. The symptom is the exact failure this list's own comment warns about: nothing failed. The
copy succeeded, the build rendered production faithfully, and the home page came out as the
empty-page placeholder — because production held the seeded layout and no content.

Parents before children, and first: a section belongs to a page, a component to a section. `galleries`
stays below them because a gallery block names a set by id carried in JSON rather than as a foreign
key — nothing enforces that order, which is why it is written down.

`site_layout` too. Production had no row at all, which reads as "the defaults" and is
indistinguishable from a setting nobody has changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 07:16:38 +01:00
pastilhasandClaude Opus 5 1d9a621bd2 publish clears and loads in one transaction
pg_dump warns that `service_nodes` carries a circular foreign key and that a --data-only dump of it
may not restore. Today the rows come out parents-first and it loads either way, but the previous shape
made that a load-bearing accident: truncate in one psql call, load in the next, so the day the
ordering changes the live site is left EMPTY until somebody notices and restores by hand.

Both statements now run as one transaction — TRUNCATE is transactional in Postgres — with foreign-key
checks off for the session. A failed load rolls the truncate back with it.

Verified against a scratch copy of production rather than reasoned about: a `create database ...
template fofos_website`, a deliberately failing load, and all nine rows still there afterwards. The
same copy confirmed what the real run will do — gallery and its nine items promoted, hero pointing at
the new file, and `users` and `contact_submissions` untouched at 2 and 8 rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 21:55:02 +01:00
pastilhasandClaude Opus 5 472fd9cb88 publish promotes development's content, then builds
The admin edits development and the build renders production, so nothing written in the panel could
reach the live site. Build was only half of publishing, and the missing half was invisible: it
succeeded, against the content somebody last promoted, and a successful build of yesterday's site
reads as a broken renderer.

Publish copies the site's content tables across and then builds. Two things it will not copy: `users`,
because production's logins are not development's and nobody should be locked out of the live site to
publish a photograph; and `contact_submissions`, the legacy inbox, because development's is empty and
production's is not — copying it would destroy real messages in order to publish nothing.

The table list is written out rather than derived. A table added later should be considered rather
than swept along, and an empty development table quietly overwriting production-only data is
discovered far too late to fix.

Order is load-bearing in two places. Production is dumped before anything is destroyed, and the
publish refuses to start if that dump fails. Development is read BEFORE production is cleared, so a
failure to read leaves production untouched rather than empty for a reason that had nothing to do with
it. `TRUNCATE ... RESTART IDENTITY`, so the sequences the copy sets are not merely ahead of the rows
it inserts — otherwise the collision arrives on the client's next save, hours later, somewhere else.

`backupAfterPublish` has been sitting in backups.ts without a caller since the day "On publish" became
a backup schedule. This is the caller.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 21:52:08 +01:00