Files
drop/server/deploy-template/quadlet
BillyOutlastandJohn Smith 6c3671714d fix(platform): repair age-rating migration drift, resolve object storage stream leaks, and add Quadlet template (#497)
* fix(server): repair age-rating migration drift

The age-ratings change (97c6f2c8) appended the AgeRatingOrganization
enum and GameAgeRating table to 20260224145112, a migration that had
already been applied to existing databases. Prisma never re-runs applied
migrations, so those databases were left without the enum/table; the
later 20260726041153_add_user_groups migration then failed with
"type AgeRatingOrganization does not exist" and game pages 500'd.

Restore 20260224145112 to its original applied content, make
20260726041153 self-healing by creating the enum when it is missing, and
add an idempotent 20260915000000_add_game_age_ratings migration that
creates the type, table, index and foreign key. All statements are
guarded so they are safe on databases already repaired out-of-band.

* fix(server): eliminate file descriptor double-close and stream leaks in object storage

* feat(server): add generic Podman Quadlet deployment template

* fix(server): address platform-stability review feedback

Migrations are now append-only: 20260224145112 and 20260726041153 are left untouched and 20260915000000_add_game_age_ratings is replaced by 20260726041152_repair_age_rating_schema, named to sort before 20260726041153 so drifted databases create the enum before add_user_groups runs. Databases whose add_user_groups row already failed still need migrate resolve --rolled-back, which is documented in the migration.

FsObjectBackend#write now truncates before writing, so overwriting an object with shorter content cannot leave stale trailing bytes. FsObjectBackend#fetchHash computes and stores the hash on a database miss (FsHashStore#get returns undefined, not null).

Quadlet: drop the README and the chunk-cache volume/env keys (the chunk cache is not implemented in this repository), fix rootless boot via default.target, add a PostgreSQL healthcheck, use the drop-postgres DNS name, and fix the uninstall volume glob.

* fix(server): grant save owners read access and enforce save size limits

Save snapshots were created with no permissions, so the desktop client
could never pull an archive back, and pruning relied on deleteWithPermission
(which requires a delete grant the object never has), silently leaking every
pruned snapshot. Grant `<userId>:read` and reclaim as the system.

The advertised saveSlotSizeLimit was also never enforced; measure the stream
and reject oversized payloads with a 413 before the full archive is written.

---------

Co-authored-by: John Smith <you@example.com>
2026-09-15 10:15:31 +10:00
..