ci(server): refuse SQL text in repositories and seeders, move the gallery oracle to tests

The repository rule that keeps dialect SQL in sql-functions.ts only
matched raw() and the sql tag, so a SQL string handed straight to the
connection, em.getConnection().execute('INSERT OR IGNORE ...'), passed
unseen, and the seeders sat outside every repository rule. A new block
refuses a string or template whose text starts like a statement as the
first argument of execute, run, all or get in src/db/repositories and
src/db/seeders; a result mode such as qb.execute('run') stays legal.
The files that already hold such SQL are named one by one so the list
can only shrink: MaintenanceRepository (PRAGMA, VACUUM INTO),
DemoRepository and six of the seven seeders.

The selector groups are named once in eslint.config.mjs, and the
selector test now also checks the new block per path, its exceptions,
and that raw() stays forbidden in repositories.

journey-gallery-order.ts exported raw SQLite ORDER BY text from
src/nest that no production code read any more since the gallery reads
moved onto JourneyPhotosRepository. Two parity tests still compare the
Kysely rebuild against it, so it moves to tests/helpers as their oracle.
This commit is contained in:
Maurice
2026-10-08 11:59:47 +02:00
parent 3fbe0418eb
commit a86aa4e819
9 changed files with 115 additions and 12 deletions
@@ -1128,7 +1128,7 @@ describe('sql-functions (sqlite)', () => {
});
// Plan 3g Task 0 (R1) — unixEpochToIsoKysely, the third fallback tier of
// `GALLERY_CHRONOLOGICAL_ORDER` (journey-gallery-order.ts). No consumer
// `GALLERY_CHRONOLOGICAL_ORDER` (tests/helpers/legacy-gallery-order.ts). No consumer
// yet: Task 1 (getJourneyFull) and Task 3 (getPublicJourney) each fold this
// into their own rebuild of the constant. The full composed ORDER BY proof
// (coalesce + nullif + correlated subquery + this helper, on a seeded
@@ -1337,7 +1337,7 @@ describe('sql-functions (sqlite)', () => {
/**
* Plan 3g Task 0 (R1) — the full Kysely rebuild of
* `journey-gallery-order.ts`'s `GALLERY_CHRONOLOGICAL_ORDER`, as a worked
* `GALLERY_CHRONOLOGICAL_ORDER` (tests/helpers/legacy-gallery-order.ts), as a worked
* example: `COALESCE(NULLIF(tp.taken_at, ''), <correlated MIN+concat
* subquery over journey_entry_photos/journey_entries>, <unixEpochToIsoKysely
* of gp.created_at>) ASC, gp.sort_order ASC, gp.id ASC`. NOT exported from