Files
siliconsolder 079013730b Add notification image proxy, expand README, fix compose env-file handling
- Proxy notification image_url server-side (GET /api/v1/notifications/:id/image)
  instead of loading it directly in the browser, so LAN-only image sources
  (e.g. Frigate snapshots) still load for clients off that network
- Tighten CSP img-src to 'self' now that images are same-origin
- Update threat model / architecture docs to match the new image-fetch design
- Expand README: Home Assistant quick-start, Pocket ID/OIDC walkthrough,
  Pangolin note, backup automation, new troubleshooting entries
- Fix docker-compose.yml: document that --env-file .env must be passed
  explicitly (Compose's implicit .env lookup was unreliable with -f from
  a different directory)
- Fix image-proxy tests to build a real session cookie (AUTH_MODE=oidc
  applies inside the test container too, so requireAuth needs one)
2026-09-07 18:49:45 +00:00

3.8 KiB
Raw Permalink Blame History

Notizarr — Phase 1 Design Package

This is the Phase 1 deliverable: architecture, threat model, data model, API design, PWA/Web Push design, Docker/Unraid design, folder structure, and the phased implementation plan. No application code is written in this phase. Per the project's own process rules, implementation (Phase 2+) does not start until this package is reviewed and the open decisions below are confirmed.

Documents

  1. 01-architecture.md — components, containers, data flow
  2. 02-threat-model.md — trust boundaries, STRIDE notes, mitigations
  3. 03-database-model.md — full Postgres schema
  4. 04-api-design.md — public app API + LAN ingestion API
  5. 05-pwa-web-push-design.md — manifest, service worker, push flow, iOS notes
  6. 06-docker-unraid-design.md — compose design, volumes, networking
  7. 07-folder-structure.md — repo layout vs. deployment layout
  8. 08-implementation-plan.md — Phase 2–10 task breakdown, mapped to MVP acceptance criteria

Open decisions that need your sign-off before Phase 2

These are the "major implementation decisions" the process asks to pause on:

# Decision Recommendation Why
1 Backend language/framework Node.js 22 + TypeScript, Fastify One language across front+back end for a solo-maintained homelab app; web-push and openid-client are the most mature libraries for the two hardest requirements (Web Push, OIDC); Fastify has first-class schema validation and low overhead.
2 ORM / migrations Drizzle ORM + drizzle-kit Typesafe, SQL-first, no native binary/engine (unlike Prisma) — simpler in a small Alpine container, plain-SQL migration files you can read and back up.
3 Realtime "instant in UI" delivery Server-Sent Events (SSE), in-process pub/sub, no Redis Single-instance app; SSE is one-way (all we need), works over plain HTTP through a reverse proxy, avoids the complexity of a WebSocket + no new infra.
4 VAPID key storage Postgres system_settings table, generated on first boot if absent Already-durable volume; no separate key file to remember to back up — pg_dump covers it automatically.
5 Attachments / image handling external_url is stored as a plain URL and rendered as <a href>, never fetched server-side. image_url is fetched server-side and proxied (GET /api/v1/notifications/:id/image) so a LAN-only image source still loads for a client off that LAN — narrowly scoped (no client-supplied URL, requires a scoped token to have set it, timeout + size cap), not a general-purpose fetch proxy. See 02-threat-model.md's SSRF section. A homelab client (phone on cellular) still needs to see camera snapshots from LAN-only sources like Frigate; a pure direct-browser-load design can't do that. Doesn't support arbitrary file uploads in v1 (can be added later as an explicit, scoped feature).
6 Webhook mapping MVP ships a fixed simple mapping ({topic, title, message, url?} JSON body, or ntfy-style headers), not a configurable templating engine Spec says "goal is easy migration, not full protocol cloning"; a mapping UI is called out as a later enhancement.
7 Topic access control Topics are visible to all authenticated users by default; an admin can mark a topic restricted and grant per-user access Matches "single/small household" simplicity principle while still satisfying "users can browse allowed topics."

If any of these should go differently, say so and I'll adjust the design before Phase 2 starts. Otherwise, confirming this package moves us into Phase 2 (repo bootstrap + Docker Compose skeleton).