docs: add base64 payload finding to SESSION-LOG and CLAUDE.md rules

This commit is contained in:
AI Assistant
2026-02-27 22:38:33 +02:00
parent c22848b471
commit 962d2a0229
2 changed files with 22 additions and 0 deletions
+4
View File
@@ -204,6 +204,10 @@ git push origin main
- **ALWAYS** use `storage.exportAll()` (namespaced) or `storage.export(namespace)` (service-level) to batch-load
- Filter items client-side after a single fetch: `for (const [key, value] of Object.entries(all)) { ... }`
- After mutations (add/update), either do optimistic local state update or a single `refresh()` — never both
- **NEVER store large binary data (base64 files) inside entity JSON** — this makes list loading transfer tens of MB
- For modules with attachments: use `exportAll({ lightweight: true })` for listing, `storage.get()` for single-entry full load
- The API `?lightweight=true` parameter strips `data`/`fileData` strings >1KB from JSON values server-side
- Future: move file data to MinIO; only store metadata (name, size, type, url) in the entity JSON
### Module Development Pattern
+18
View File
@@ -56,6 +56,24 @@ With 6 registry entries + ~10 contacts + ~20 tags, the Registratura page fired *
### Commits
- `c45a30e` perf: fix N+1 query pattern across all modules + rack numbering
- `c22848b` perf(registratura): lightweight API mode strips base64 attachments from list
### Second Root Cause — Base64 Attachment Payloads (found after first fix)
After deploying the N+1 fix, Registratura STILL loaded in 2+ minutes. Deeper investigation revealed:
**Root cause:** `RegistryAttachment.data` stores full base64-encoded files directly in JSON. A 5MB PDF = ~6.7MB base64. With 6 entries having attachments, `/api/storage?namespace=registratura` returned **30-60MB of JSON** on every page load.
**Fix:** Added `?lightweight=true` parameter to the API route. Server-side `stripHeavyFields()` recursively strips large `data` and `fileData` string fields (>1KB) from JSON, replacing with `"__stripped__"`. List loading now transfers ~100KB. Full entry data loaded on-demand only when editing (single entry = manageable).
**Additional files:**
- `src/app/api/storage/route.ts``stripHeavyFields()` + lightweight param
- `src/core/storage/types.ts``export()` accepts `{ lightweight?: boolean }`
- `src/core/storage/adapters/database-adapter.ts` — passes flag to API
- `src/modules/registratura/services/registry-service.ts``getAllEntries()` uses `lightweight: true`, new `getFullEntry()`
- `src/modules/registratura/hooks/use-registry.ts` — exports `loadFullEntry()`
- `src/modules/registratura/components/registratura-module.tsx``handleEdit` loads full entry on demand
---