fix(library): pagineer bestanden in de folder-browser #61

Merged
janpeter merged 1 commit from fix/library-folder-view-paging into main 2026-07-29 13:50:43 +02:00
Owner

Probleem

/library viel om zodra je een groot album opende. De gebruiker zag het generieke "Startup fout / App kon niet starten"-scherm, dat naar /api/ready en de database wijst — maar /api/ready gaf gewoon 200 {"status":"ready"}. De echte fout stond in de container-log:

2026-07-29T11:17:15Z ⨯ RangeError: Maximum call stack size exceeded
  clientVersion: '7.8.0',  digest: '1932943857'

en eerder al, op andere albums:

⨯ PrismaClientKnownRequestError: Invalid `prisma.slideshowImage.findMany()` invocation:
  The query parameter limit supported by your database is exceeded.  (P2029)

Oorzaak

De folder-browser haalde álle bestanden van een node in één keer op. src/actions/storage.ts riep listSlideshowImagesForAlbum() aan zonder venster, en album library-imports/motherless bevat 437.421 images.

De window-parameter uit #59 is destijds wél toegevoegd aan de slideshow-routes (library/[category]/page.tsx, library/[category]/[album]/page.tsx), maar niet aan het pad dat /library zelf gebruikt: MediaGridlistFolderFileslistSlideshowImagesForAlbum. De draaiende image bevatte de fix van #59 dus wel — dit was een gemiste plek, geen stale deploy.

Een sweep over alle 1970 library-nodes op de productie-database gaf precies drie kapotte nodes:

Node Images Fout
library:album:library-imports/motherless 437.421 RangeError
library:album:library-imports/shared-photos 53.670 P2029
library:album:library-imports/celebs 51.404 P2029
library:album:library-imports/stars 6.118 OK

Oplossing

  • listFolderFiles(nodeId, window?) geeft het venster door aan alle takken — album, collectie, favorieten, prullenbak, import-folder en Immich-persoon. Die waren stuk voor stuk onbegrensd; alleen albums waren nu groot genoeg om te crashen.
  • listManualFavoriteImages, listSlideshowImagesForTrash, listSlideshowImagesForCollection, listLibraryImportFiles en listImmichPersonMediaFiles accepteren een venster.
  • Nieuwe hook useFolderFiles laadt per LIBRARY_FOLDER_PAGE_SIZE (500) en vraagt er telkens één extra op om te weten of er meer is. MediaGrid en LibraryMixedContent tonen een "Meer laden"-knop zolang dat zo is.
  • mediaWindowArgs staat nu gedeeld in folder-browser.ts; slideshow.ts gebruikt het ook, zodat de clamping-logica niet op twee plekken kan gaan afwijken.

Folders die in één pagina passen zien er ongewijzigd uit — de knop rendert alleen als er echt meer is.

Verificatie

De aangepaste server-action tegen de live database op max2:

OK  library:album:library-imports/motherless       1043ms  n=500  meer=true
OK  library:album:library-imports/shared-photos     131ms  n=500  meer=true
OK  library:album:library-imports/celebs            127ms  n=500  meer=true
OK  library:album:library-imports/stars              32ms  n=500  meer=true
OK  library:system:favorites                           8ms  n=92   meer=false
OK  library:system:trash                               8ms  n=8    meer=false
OK  motherless offset=   500                        899ms  n=500  meer=true
OK  motherless offset=400000                       1453ms  n=500  meer=true

Verder: npm run build groen, npx tsc --noEmit zonder nieuwe fouten, npx eslint terug op baseline. npm test gaat van 296 naar 302 tests (6 nieuwe regressietests); de 20 falende tests zijn identiek vóór en ná deze branch — het zijn allemaal DB-integratietests die zonder DATABASE_URL niet kunnen draaien.

Bekende beperking

Het filterveld in de folder-view filtert client-side over de geladen bestanden. Bij een gepagineerd album zoekt het dus binnen wat je tot nu toe hebt geladen. Dat gedrag bestond al, maar wordt met paginering zichtbaarder; echte server-side filtering is een aparte wijziging.

🤖 Generated with Claude Code

## Probleem `/library` viel om zodra je een groot album opende. De gebruiker zag het generieke "Startup fout / App kon niet starten"-scherm, dat naar `/api/ready` en de database wijst — maar `/api/ready` gaf gewoon `200 {"status":"ready"}`. De echte fout stond in de container-log: ``` 2026-07-29T11:17:15Z ⨯ RangeError: Maximum call stack size exceeded clientVersion: '7.8.0', digest: '1932943857' ``` en eerder al, op andere albums: ``` ⨯ PrismaClientKnownRequestError: Invalid `prisma.slideshowImage.findMany()` invocation: The query parameter limit supported by your database is exceeded. (P2029) ``` ## Oorzaak De folder-browser haalde álle bestanden van een node in één keer op. `src/actions/storage.ts` riep `listSlideshowImagesForAlbum()` aan zonder venster, en album `library-imports/motherless` bevat **437.421** images. De `window`-parameter uit #59 is destijds wél toegevoegd aan de slideshow-routes (`library/[category]/page.tsx`, `library/[category]/[album]/page.tsx`), maar niet aan het pad dat `/library` zelf gebruikt: `MediaGrid` → `listFolderFiles` → `listSlideshowImagesForAlbum`. De draaiende image bevatte de fix van #59 dus wel — dit was een gemiste plek, geen stale deploy. Een sweep over alle 1970 library-nodes op de productie-database gaf precies drie kapotte nodes: | Node | Images | Fout | |---|---:|---| | `library:album:library-imports/motherless` | 437.421 | RangeError | | `library:album:library-imports/shared-photos` | 53.670 | P2029 | | `library:album:library-imports/celebs` | 51.404 | P2029 | | `library:album:library-imports/stars` | 6.118 | OK | ## Oplossing - `listFolderFiles(nodeId, window?)` geeft het venster door aan **alle** takken — album, collectie, favorieten, prullenbak, import-folder en Immich-persoon. Die waren stuk voor stuk onbegrensd; alleen albums waren nu groot genoeg om te crashen. - `listManualFavoriteImages`, `listSlideshowImagesForTrash`, `listSlideshowImagesForCollection`, `listLibraryImportFiles` en `listImmichPersonMediaFiles` accepteren een venster. - Nieuwe hook `useFolderFiles` laadt per `LIBRARY_FOLDER_PAGE_SIZE` (500) en vraagt er telkens één extra op om te weten of er meer is. `MediaGrid` en `LibraryMixedContent` tonen een **"Meer laden"**-knop zolang dat zo is. - `mediaWindowArgs` staat nu gedeeld in `folder-browser.ts`; `slideshow.ts` gebruikt het ook, zodat de clamping-logica niet op twee plekken kan gaan afwijken. Folders die in één pagina passen zien er ongewijzigd uit — de knop rendert alleen als er echt meer is. ## Verificatie De aangepaste server-action tegen de live database op max2: ``` OK library:album:library-imports/motherless 1043ms n=500 meer=true OK library:album:library-imports/shared-photos 131ms n=500 meer=true OK library:album:library-imports/celebs 127ms n=500 meer=true OK library:album:library-imports/stars 32ms n=500 meer=true OK library:system:favorites 8ms n=92 meer=false OK library:system:trash 8ms n=8 meer=false OK motherless offset= 500 899ms n=500 meer=true OK motherless offset=400000 1453ms n=500 meer=true ``` Verder: `npm run build` groen, `npx tsc --noEmit` zonder nieuwe fouten, `npx eslint` terug op baseline. `npm test` gaat van 296 naar 302 tests (6 nieuwe regressietests); de 20 falende tests zijn identiek vóór en ná deze branch — het zijn allemaal DB-integratietests die zonder `DATABASE_URL` niet kunnen draaien. ## Bekende beperking Het filterveld in de folder-view filtert client-side over de *geladen* bestanden. Bij een gepagineerd album zoekt het dus binnen wat je tot nu toe hebt geladen. Dat gedrag bestond al, maar wordt met paginering zichtbaarder; echte server-side filtering is een aparte wijziging. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(library): pagineer bestanden in de folder-browser
Some checks failed
CI / docker-build (pull_request) Failing after 3s
6deff1a014
Het openen van een groot album in /library liet de pagina crashen met
"RangeError: Maximum call stack size exceeded" (digest 1932943857) of
Prisma P2029 "query parameter limit exceeded". De folder-browser haalde
alle bestanden van een node in één keer op; `library-imports/motherless`
bevat 437.421 images.

De `window`-parameter uit #59 zat alleen op de slideshow-routes
(library/[category] en library/[category]/[album]) en niet op het pad dat
/library zelf gebruikt: listFolderFiles -> listSlideshowImagesForAlbum.

- listFolderFiles krijgt een optioneel `window` en geeft dat door aan
  álle takken (album, collectie, favorieten, prullenbak, import-folder,
  Immich-persoon) — die waren stuk voor stuk onbegrensd.
- listManualFavoriteImages, listSlideshowImagesForTrash,
  listSlideshowImagesForCollection, listLibraryImportFiles en
  listImmichPersonMediaFiles accepteren nu een venster.
- Nieuwe hook useFolderFiles laadt per LIBRARY_FOLDER_PAGE_SIZE (500) en
  vraagt er één extra op om te weten of er meer is; MediaGrid en
  LibraryMixedContent tonen een "Meer laden"-knop zolang dat zo is.
- mediaWindowArgs gedeeld in folder-browser.ts; slideshow.ts gebruikt het
  nu ook, zodat de clamping-logica niet op twee plekken staat.

Folders die in één pagina passen zien er ongewijzigd uit: de knop rendert
alleen als er echt meer is.

Geverifieerd tegen de live database op max2: motherless, shared-photos en
celebs laden nu in 130-1050 ms, ook op offset 400.000; favorieten (92) en
prullenbak (8) leveren alles zonder knop.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
s4m-codex-reviewer left a comment

Verdict: COMMENT

geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.

Findings

  • warning — src/components/MediaGrid.tsx:36: filterLibraryItems draait nu alleen op de reeds geladen pagina. Voor folders met meer dan 500 bestanden kan een zoekterm die alleen in een latere pagina voorkomt eerst "Geen resultaten" tonen, terwijl het bestand wel bestaat. De LoadMoreFiles-knop blijft zichtbaar, maar de zoeksemantiek is regressief t.o.v. de oude volledige client-side lijst; overweeg expliciet te maken dat filteren alleen geladen items raakt, of een server-side zoek/paginatiepad toe te voegen.

Geen blokkerende findings gevonden. De backend-paginatie wordt consequent doorgegeven naar Immich-personen, library-folders/imports, favorieten, prullenbak, albums en collections, en er zijn gerichte unit-tests toegevoegd voor mediaWindowArgs en de slideshow-querybegrenzing.

# Verdict: COMMENT geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden. ## Findings - warning — src/components/MediaGrid.tsx:36: `filterLibraryItems` draait nu alleen op de reeds geladen pagina. Voor folders met meer dan 500 bestanden kan een zoekterm die alleen in een latere pagina voorkomt eerst "Geen resultaten" tonen, terwijl het bestand wel bestaat. De `LoadMoreFiles`-knop blijft zichtbaar, maar de zoeksemantiek is regressief t.o.v. de oude volledige client-side lijst; overweeg expliciet te maken dat filteren alleen geladen items raakt, of een server-side zoek/paginatiepad toe te voegen. Geen blokkerende findings gevonden. De backend-paginatie wordt consequent doorgegeven naar Immich-personen, library-folders/imports, favorieten, prullenbak, albums en collections, en er zijn gerichte unit-tests toegevoegd voor `mediaWindowArgs` en de slideshow-querybegrenzing.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
janpeter/Media-Organizer!61
No description provided.