Commit Graph

155 Commits

Author SHA1 Message Date
jubnl 7ee0403eaf refactor(reservations): reservations, endpoints and travelers through repositories 2026-09-23 14:58:36 +02:00
jubnl 3a26d03b00 refactor(roadtrip): roadtrip tables through repositories 2026-09-23 14:44:10 +02:00
jubnl 93324e71c4 feat(server): plan 3d groundwork — dialect helpers, visibility predicate, feed and cron context ratchets 2026-09-23 13:52:38 +02:00
jubnl 175eb3b11b fix(server): plan 3c close-out — non-finite ids bound as NULL, trip id parsed once at every places/days/ws gate
Platform: NulSafeSqlitePlatform now renders a bound NaN as NULL and
+/-Infinity as 9e999/-9e999, matching better-sqlite3's own legacy binding
(rule 22 extension) — the program-wide fail-safe for any caller that still
passes an unguarded Number(untrusted) into a converted statement.

PlacesService.verifyTripAccess and RealtimeGateway.handleJoin stop doing
that: verifyTripAccess parses once with toRowId and threads the parsed id
through create/import/bulk/rating/export.gpx (deleting the seven
toRowId(tripId) ?? -1 sites), and handleJoin gets a Number.isFinite guard.
DaysService gets the same treatment across list/create/getDay/reorder/
insert/resyncAccommodationDays, closing the gap where a hex-spelled trip id
could renumber a real trip's days while the raw-bind inverted-accommodation
guard silently matched nothing.

DatabaseService.getTripTitle is deleted; PlacesService injects
TripsRepository directly and calls getTitle itself.

Template/cheap-item cleanup: DayAssignmentsRepository.listForTimeSort uses
$castTo instead of an unknown bridge; the duplicated TagRow interface in
Places.repository.ts is now imported from Tags.repository.ts;
AssignmentWithPlaceRow extends the guarded DayAssignmentRow instead of
restating its columns; PlaceShadowPicksRepository.totals drops its
unreachable ??-fallback branch; Places.repository.ts's updatePlace types
the NOT NULL name column as string; trip-members.service.ts's
transferOwnership threads one parsed trip id through all three writes and
corrects two stale "raw-bind seam" docstrings that were actually Number()
seams; a dead canAccessTrip mock is removed from reservations.e2e.test.ts.

Tests: the 23 new no-explicit-any warnings in TRIP-SVC-069 are typed
(lint back to 2416); HTTP and WS regression coverage for the non-finite
and non-canonical id shapes across places/days routes, mutation-proved;
TRIP-JOIN-005 asserts the exact concurrent-join settlement instead of
>= 1; a new tests/unit/db/transaction-yield.test.ts pins rule 24's
measured transaction-yield/dirty-read/nested-BEGIN behaviour.
2026-09-23 12:22:36 +02:00
jubnl 18a4784ebd refactor(trips): trips through repositories 2026-09-23 09:33:48 +02:00
jubnl f19face405 refactor(places): import paths through repositories 2026-09-23 08:53:54 +02:00
jubnl 94c6efbbcc refactor(trip-members): membership, guests and the trip read model through repositories 2026-09-23 08:00:39 +02:00
jubnl cee6310e59 refactor(server): trip-membership, place-shadow, place-enrichment, place-photos and query helpers through repositories 2026-09-23 06:41:03 +02:00
jubnl f41da98df3 refactor(assignments): day assignments through repositories 2026-09-23 06:27:21 +02:00
jubnl d7f5bc64c1 refactor(days): days and day notes through repositories 2026-09-23 05:31:36 +02:00
jubnl d2e0d7e320 refactor(trips): trip access through TripsRepository; demo seed in a request context; dialect helpers for the trips cluster 2026-09-23 04:46:18 +02:00
jubnl 769b9577ec refactor(server): trip-access primitives async at every caller 2026-09-23 02:46:39 +02:00
jubnl 33b9488653 refactor(auth): AuthService and account cleanup through repositories 2026-09-22 23:17:17 +02:00
jubnl daef15be70 refactor(tokens): MCP and API tokens through McpTokensRepository 2026-09-22 20:23:11 +02:00
jubnl 57f4e29b9a refactor(auth): users table through UsersRepository; JWT and MFA lookups repository-backed 2026-09-22 19:39:01 +02:00
jubnl 66703efeb7 feat(db): generated entities declare their repository type; test casts dropped 2026-09-22 18:01:45 +02:00
jubnl 761cd14b2b fix(server): plan 3a review follow-ups — fail closed without an ORM at every choke point; seam and D5 ratchet tests; dead method and DDL copies removed 2026-09-22 16:54:45 +02:00
jubnl 6fafcd72f2 fix(settings): drop dead wiring and the speculative deleteForUser; strict row assertions 2026-09-22 15:47:02 +02:00
jubnl 59fa932ec8 test(server): harness constructors follow the Task 5 repository signatures; one test ORM per handle in the plugin host 2026-09-22 15:19:58 +02:00
jubnl 6763648c45 refactor(settings): user and instance settings through repositories
SettingsRepository (getForUser/upsertForUser/getOne/deleteForUser) replaces
the per-user settings table's raw SQL; SettingsService drops DatabaseService
entirely. instance-api-keys.ts's readInstanceApiKey/writeInstanceApiKey/
resolveApiKey take an explicit AppSettingsRepository/UsersRepository instead
of a raw connection.

An earlier version resolved those two repositories itself from the active
MikroORM request context, so none of its six callers needed to change. That
worked in production and e2e (always inside a real request) but broke
service construction in plain unit tests across every calling domain
(addons, auth x2, maps, transit, unsplash - 185 failures on a full run),
since none of them wrap a request context. Each of those six services now
injects its own AppSettingsRepository/UsersRepository and passes them
through explicitly, matching how every other converted repository in this
migration is consumed; their own SQL is untouched (outside Plan 3a).
2026-09-22 15:08:49 +02:00
jubnl 98e906a88e chore(addons): well-known gate wraps only the addon read in a request context; drop unused test factories 2026-09-22 14:23:39 +02:00
jubnl 6db91c8bf3 refactor(addons): addon catalog and photo providers through repositories 2026-09-22 14:06:57 +02:00
jubnl aa1067035f refactor(categories, tags): repositories replace raw SQL 2026-09-22 13:54:13 +02:00
jubnl e9391a9ae1 fix(server): non-HTTP entrypoints run inside an ORM request context; permission loads fail closed on context errors 2026-09-22 13:25:17 +02:00
jubnl b0905f9867 docs(db): owned-lookup call-site convention; refresh side effect; e2e ORM module spread notes 2026-09-22 12:53:47 +02:00
jubnl 4209343328 fix(db): PK reads refresh past the identity map; typed owned-lookup generics; e2e ORM module mirrors production config 2026-09-22 12:38:59 +02:00
jubnl 7908914345 refactor(permissions): permission flags through AppSettingsRepository 2026-09-22 12:30:20 +02:00
jubnl f460ae4fcb feat(db): AppSettings and Users repositories; forFeature wiring pattern 2026-09-22 12:06:13 +02:00
jubnl ae2af05cad fix(server): phase 1 review follow-ups — awaited returns, logged upload-filter rejections, covered handshake/notice branches, call-graph gate in CI, dead test imports 2026-09-22 07:54:09 +02:00
jubnl 869d139412 refactor(reservations, booking-import, calendar, integrations, roadtrip): async DB-touching methods; transactions through UnitOfWork 2026-09-22 06:11:41 +02:00
jubnl 5c8decd3ea refactor(assignments, public-api, accommodations, places): async DB-touching methods; transactions through UnitOfWork 2026-09-22 05:21:48 +02:00
jubnl 845320e0a4 refactor(journey, oidc, place-enrichment, tokens, trip-members): async DB-touching methods; transactions through UnitOfWork 2026-09-22 04:16:07 +02:00
jubnl cb177ce655 refactor(vacay, admin, doc-sync): async DB-touching methods; transactions through UnitOfWork 2026-09-22 03:29:33 +02:00
jubnl 37992de7ab refactor(memories, photos, packing, share): async DB-touching methods; transactions through UnitOfWork 2026-09-22 02:21:06 +02:00
jubnl 6b755314d8 refactor(collab, collections, maps): async DB-touching methods; transactions through UnitOfWork 2026-09-22 01:49:18 +02:00
jubnl 4df2d83137 refactor(notifications, place-photos, backup): async DB-touching methods; transactions through UnitOfWork 2026-09-22 00:22:11 +02:00
jubnl fac181f45b chore(plugins): drop gate-only asyncs; observe the scheduler's rejection; async event-sink stub 2026-09-22 00:12:56 +02:00
jubnl e28dc6de28 refactor(plugins): async DB-touching methods; transactions through UnitOfWork 2026-09-22 00:00:53 +02:00
jubnl e413308227 refactor(llm-parse, mcp-shared, oauth, place-shadow, route-usage, storage, todo, trip-invite): async DB-touching methods; transactions through UnitOfWork 2026-09-21 23:27:01 +02:00
jubnl aa587e2fb6 refactor(budget, common, day-notes, days): async DB-touching methods; transactions through UnitOfWork 2026-09-21 22:39:11 +02:00
jubnl 953e2526bb refactor(atlas, school-holidays, settings): async DB-touching methods; transactions through UnitOfWork 2026-09-21 21:23:10 +02:00
jubnl 0cf99a9939 refactor(realtime, systemNotices, addons, airports, audit, categories, permissions, query-helpers, tags, transit, trip-membership): async DB-touching methods; transactions through UnitOfWork 2026-09-21 20:48:03 +02:00
jubnl 27d044f9e8 chore(server): promise safety net and sweep tooling for the async migration 2026-09-21 19:01:38 +02:00
jubnl ef184ec7c2 test(server): ORM suites open the schema snapshot; RESET_TABLES derived from the schema 2026-09-21 18:12:07 +02:00
jubnl 418bd1c6b5 fix(test): route MikroORM's dynamic imports through vitest from the setup file, not the ORM config 2026-09-21 10:35:16 +02:00
jubnl 2bc9e927be test(server): snapshot harness keeps the legacy id semantics 2026-09-21 10:22:18 +02:00
jubnl e846c91a16 test(server): integration suites boot on the migrated schema snapshot 2026-09-21 10:13:40 +02:00
jubnl d7f39916d5 feat(db): request-context and unit-of-work helpers for the ORM, with concurrency tests 2026-09-21 10:01:36 +02:00
jubnl 565f72740b test(db): createTestOrm binds an ORM to a suite's own SQLite handle 2026-09-21 09:17:17 +02:00
Maurice 77a16d6f26 fix(places): deleting a place cancels the nights booked at it
A stay whose place was deleted kept its row with place_id NULL: still drawn in the
day header, still naming a hotel through its partner booking, and pointing
nowhere. Nothing could reach it any more and nothing cleaned it up.

It goes with the place now, through the accommodations domain rather than a
DELETE in the places path, because a stay takes its partner booking, that
booking's expense and the day stop it wrote with it — none of which is the places
domain's business to know. Both delete paths, single and bulk.

The service moves into an AccommodationsDomainModule, the assignments-domain
precedent: the service never touches PlacesService, only the MCP tool that writes
a place and a stay together does, so it can sit in a module PlacesModule is free
to import without closing a loop. AccommodationsModule keeps exporting it, so
every existing consumer is unchanged.
2026-09-13 15:36:02 +02:00