Commit Graph

1905 Commits

Author SHA1 Message Date
jubnl af85d39799 test(server): close slice-4 gaps surfaced by the full tier 2026-08-17 06:32:32 +02:00
jubnl 5870dd4fda feat(journey): journey-thumbs orphan sweep and delete-site derived-artifact reclaim 2026-08-17 06:23:13 +02:00
jubnl 616897b60b fix(memories): reclaim orphaned trek photo cache objects in the ttl sweep 2026-08-17 06:19:31 +02:00
jubnl 0962df2f22 refactor(journey): photo deletion through storage 2026-08-17 06:17:24 +02:00
jubnl 939c2ec3e8 refactor(memories): immich upload reads through storage; drop uploads-root 2026-08-17 06:15:01 +02:00
jubnl 364f376b07 refactor(memories): thumbnail service category-addressed 2026-08-17 06:08:04 +02:00
jubnl 1a2e4d4ef2 refactor(memories): trek photo cache internals through storage 2026-08-17 06:05:52 +02:00
jubnl f8faef77c4 refactor(files): trash deletion through storage 2026-08-17 06:01:28 +02:00
jubnl f382a7635e refactor(collab): note-file deletion through storage 2026-08-17 05:51:44 +02:00
jubnl dfb8f8a8a4 refactor(auth): avatar reclaim through storage 2026-08-17 05:47:31 +02:00
jubnl 8a3327c5f6 refactor(trips): trip covers through storage 2026-08-17 05:37:52 +02:00
jubnl 965566369e refactor(places): reclaim place images and collection covers through storage 2026-08-17 05:31:53 +02:00
jubnl 4eca78b53e refactor(place-photos): route place-photo cache through storage 2026-08-17 05:20:09 +02:00
jubnl d27e54952a test(storage): raise src/nest/storage branches pin 2026-08-16 18:36:43 +02:00
jubnl 31478e232a test(server): close serving-swap gaps surfaced by the full tier 2026-08-16 18:36:38 +02:00
jubnl 94490b7d31 fix(share): answer place-photo cache miss with 204 like the maps proxy 2026-08-16 11:16:17 +02:00
jubnl afd6d297c0 refactor(journey): serve public journey assets through storage 2026-08-16 11:12:28 +02:00
jubnl 1bf6517b75 refactor(share): stream shared place-photo bytes through storage 2026-08-16 11:07:04 +02:00
jubnl 786b1f5c07 refactor(maps): stream place-photo bytes through storage 2026-08-16 11:04:04 +02:00
jubnl 980f8be6e8 refactor(memories): serve photo bytes through storage 2026-08-16 10:54:06 +02:00
jubnl a0a5bb8203 refactor(files): serve trip-file downloads through storage 2026-08-16 10:50:28 +02:00
jubnl 4527e8688d refactor(platform): serve /uploads routes through storage 2026-08-16 10:46:01 +02:00
jubnl 36f3f89e14 test(storage): raise src/nest/storage coverage pin 2026-08-16 10:08:51 +02:00
jubnl 9ef886bbdd test(files): key FILE-P02 residue checks on upload size 2026-08-16 10:08:33 +02:00
jubnl db3c5da04e fix(storage): age-gate the boot spool sweep 2026-08-16 09:53:26 +02:00
jubnl 92c87d1f3a test(db): re-point the trailing-migration guard at the trip_files prefix strip 2026-08-16 09:53:26 +02:00
jubnl f9d84f5907 fix(storage): default defParamCharset to utf8 in the upload factory 2026-08-16 09:53:25 +02:00
jubnl b72645272b fix(server): consolidate allowed_file_types onto AllowedFileTypesService 2026-08-16 09:49:46 +02:00
jubnl c75d431e4c refactor(auth): spool avatar upload through storage 2026-08-16 09:46:27 +02:00
jubnl 8b0c768ba0 refactor(places): spool place-image and collection uploads through storage 2026-08-16 09:44:03 +02:00
jubnl 7e91f1abaf refactor(trips): spool trip cover upload through storage 2026-08-16 09:38:26 +02:00
jubnl b1abfd2110 refactor(journey): spool journey media uploads through storage 2026-08-16 09:34:48 +02:00
jubnl fd81ee00f1 refactor(collab): spool note attachments through storage; normalize files/ prefix 2026-08-16 09:29:46 +02:00
jubnl 428d32b18a refactor(files): spool trip-file uploads through storage 2026-08-16 09:25:19 +02:00
jubnl 7ae7295e1e feat(storage): multer upload options factory 2026-08-16 09:21:15 +02:00
jubnl bad01a2fd6 test(storage): pin src/nest/storage coverage thresholds 2026-08-16 00:27:55 +02:00
jubnl 75d5bbcfc2 feat(storage): settings-backed registry, StorageService facade, module wiring 2026-08-16 00:21:22 +02:00
jubnl 09d27d633a feat(server): add TREK_UPLOADS_DIR env var for the uploads root 2026-08-16 00:05:12 +02:00
jubnl 5ad1670bd9 feat(storage): MirrorDriver composite backend 2026-08-16 00:00:26 +02:00
jubnl 19f18a2b3a feat(storage): storage key validation, driver contract suite, LocalDriver 2026-08-15 23:54:43 +02:00
jubnl b1e4c830b2 fix(immich): strip leading / in immich url (#1948) 2026-08-15 23:05:44 +02:00
jubnl 2bffee8fd4 fix(auth): preserve remember-me when password change re-issues the session (#1927) 2026-08-15 22:48:22 +02:00
jubnl 72221a2e45 feat(auth): sliding session renewal past half the token lifetime (#1927) 2026-08-15 22:48:16 +02:00
jubnl 61e03fdfde feat(oidc): honor remember-me in SSO login (#1927) 2026-08-15 22:48:03 +02:00
Maurice cb41d082be feat(admin): make an admin section linkable with ?tab=
The admin page always opened on Users, whatever the address said. A support
reply, an onboarding mail or a bookmark could point at the page but not at the
panel it was about, so every one of them ended with "then click X on the left".

Read once for the initial value and written back on each change, so the address
bar keeps saying where the reader is. Replaced rather than pushed: eleven tabs
would otherwise fill the back button with the history of a single page.
2026-08-15 18:07:21 +02:00
Maurice a6c27aac51 fix(admin): stop asking for OIDC config where the route is closed
On a centrally administered install /api/admin/oidc answers 403, and the admin
page asked anyway. The promise was caught, so nothing broke, but the request
still went out and still printed a red 403 in the console of every admin who
opened the page. Swallowing a rejection hides a failure from the code, not from
the person reading the console.
2026-08-15 18:07:21 +02:00
Maurice f2329c9a63 feat(client): let a managed surface attach as an admin tab
The nav-entry seam was the wrong shape for what actually attaches here. A
subscription surface is about the install, not about a trip: /admin is already
behind an admin check, already grouped, and already where somebody looks to
change how their instance works. A top-level nav entry put it beside My Trips
for a screen opened once a month by one person.

Two lines in AdminPage rather than an overlay replacing the file: the tab list
gets the extra entries appended per group, and the body renders whichever one is
active. Appended rather than inserted because PageSidebar needs a group's tabs
contiguous.

The route and nav-entry seams stay. They are the right answer for a surface that
genuinely is a page, and both remain empty here.
2026-08-15 18:07:21 +02:00
Maurice 887e6c5026 feat(client): let a managed route require an admin
Hiding the nav entry is not access control: the path stays typeable, and a screen
about how the install is run should not open for somebody who was invited to one
trip. ProtectedRoute already knows how to refuse — the attachment point just was
not asking it to.

Optional, so a route that does not set it behaves exactly as before. It sits
next to adminOnly on the nav entry rather than being derived from it, because
the two answer different questions: who is offered the door, and who may walk
through it.
2026-08-15 18:07:21 +02:00
Maurice 7c378c574f feat(client): let a managed nav entry be admin-only
The attachment point hands the two nav bars a static list, so anything attached
there showed up for every user of the instance. What belongs there is the
operator's side of the install, and a trip's other travellers are on the instance
as guests of the person who runs it — an entry about how it is run is noise to
them.

`adminOnly` is optional and absent means "for everyone", so nothing that exists
today changes meaning. Both nav bars go through the same exported filter rather
than each writing the rule, since a rule written twice is a rule that will differ.

Still inert here: the list is empty, and the tests pin that an empty list stays
empty for either kind of user.
2026-08-15 18:07:21 +02:00
Maurice 05315ef7d9 fix(planner): pin the clock in the opening-hours test
FE-PDC-019 asserts that the collapsed row shows one specific line, but the row
shows the current day in the place's timezone — and the fixture gives Saturday
different hours from the working week. So the test passed Monday to Friday and
took the build down every weekend, which reads as a broken feature rather than a
test that forgot to say which day it is standing on.

Pinned to a Wednesday, with the Saturday case kept as its own test rather than
thrown away: it is the one that proves the day lookup happens at all, and it is
the exact case that was failing.
2026-08-15 18:07:21 +02:00