From 829d0a2caa484c809e05b2a1238da2529299be03 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Thu, 7 May 2026 10:57:23 +0100 Subject: [PATCH] Update docs for Presto, PubSub, and Node.js 26 Add Presto companion display to architecture overview. Document collection API cover sizes (cover, thumb/480px, mini/150px, micro/40px). Update PubSub topic table and LiveView conventions for handle_params subscription management. Bump Node.js version from 25 to 26 in production infrastructure. --- docs/architecture.md | 11 ++++++----- docs/production-infrastructure.md | 2 +- docs/project-conventions.md | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index dd6c0d6f..19b51a9b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -19,6 +19,7 @@ Key capabilities: - AI-powered record chat via OpenAI streaming with web search - Barcode scanning for quick imports - Encrypted secret storage (Cloak) +- Presto companion display (MicroPython, 4" IPS LCD, "Records on this day") **Elixir ~> 1.14, Phoenix ~> 1.8, LiveView ~> 1.1, SQLite3** @@ -249,10 +250,10 @@ HTTP 429 into `:rate_limit` vs `:auth_error` by reading the body `code` ## PubSub Topics -| PubSub | Topic Pattern | Message | Used By | -| ---------------- | -------------------------- | ------------------- | ------------------------------------------------------------------ | -| `:music_library` | `"records:#{id}"` | `{:update, record}` | CollectionLive.Show, WishlistLive.Show — real-time record updates | -| `:music_library` | `"listening_stats:update"` | `%{track_count: n}` | StatsLive.Index, ScrobbledTracksLive.Index — new scrobbles arrived | +| PubSub | Topic Pattern | Message | Used By | +| ---------------- | -------------------------- | ------------------- | ---------------------------------------------------------------------------------------------- | +| `:music_library` | `"records:#{id}"` | `{:update, record}` | CollectionLive.Show, WishlistLive.Show — subscribe in handle_params, unsubscribe on navigation | +| `:music_library` | `"listening_stats:update"` | `%{track_count: n}` | StatsLive.Index, ScrobbledTracksLive.Index — new scrobbles arrived | --- @@ -345,7 +346,7 @@ All authenticated routes live inside a single `live_session` with three `on_moun | `LastFmController` | `/auth/last_fm/callback` | Last.fm OAuth | | `ArchiveController` | `/backup`, `/api/v1/backup` | Database backup download (API route requires token) | | `AssetController` | `/assets/:transform_payload`, `/public/assets/:transform_payload`, `/api/v1/assets/:transform_payload` | Serve images with transforms (public route for emails, API route requires token) | -| `CollectionController` | `/api/v1/collection/*` | JSON API for collection queries | +| `CollectionController` | `/api/v1/collection/*` | JSON API for collection queries (returns 4 cover sizes: cover, thumb/480px, mini/150px, micro/40px) | | `ErrorController` | `/api/v1/errors`, `/api/v1/errors/:id`, `/api/v1/errors/:id/mute`, `/api/v1/errors/:id/unmute`, `/api/v1/errors/:id/resolve`, `/api/v1/errors/:id/unresolve` | JSON API for production error queries and mutations (requires Bearer token); POST endpoints for mute/unmute/resolve/unresolve | --- diff --git a/docs/production-infrastructure.md b/docs/production-infrastructure.md index 7e479469..ebc65f4e 100644 --- a/docs/production-infrastructure.md +++ b/docs/production-infrastructure.md @@ -29,7 +29,7 @@ push via GitHub Actions. The Docker image is a multi-stage build: 1. **Builder** — `hexpm/elixir:1.20.0-rc.4-erlang-28.5-debian-trixie-20260421-slim` with - Node.js 25, compiles deps, builds assets (`mix assets.deploy`), generates an OTP release. + Node.js 26, compiles deps, builds assets (`mix assets.deploy`), generates an OTP release. 2. **Runner** — `debian:trixie-20260421-slim` with minimal runtime deps (`libstdc++6`, `openssl`, `libncurses6`, `ca-certificates`). Runs as unprivileged `nobody` user. diff --git a/docs/project-conventions.md b/docs/project-conventions.md index 7703448b..2e90791f 100644 --- a/docs/project-conventions.md +++ b/docs/project-conventions.md @@ -20,7 +20,7 @@ Key rules: imperative present tense, single-line under 60 characters, task ID pr - **Context modules own all queries.** LiveViews never query the database directly -- they call context functions. - **Schemas hold pure accessor/helper functions** on the struct (e.g., `RecordSet.count_by_status/1`). No side effects in schemas. -- **LiveView standard structure:** `mount/3` sets `@current_section`, `handle_params/3` loads data and sets `@page_title` (via pattern-matched private `page_title/2`), `handle_info/2` receives LiveComponent messages. +- **LiveView standard structure:** `mount/3` sets `@current_section`, `handle_params/3` loads data, sets `@page_title` (via pattern-matched private `page_title/2`), and manages PubSub subscriptions via `LiveHelpers.RecordActions.manage_subscription/2` (unsubscribing from the previous record and subscribing to the new one). `handle_info/2` receives LiveComponent messages and validates inbound record updates against `socket.assigns.record.id` to discard stale messages. - **LiveComponents communicate with parent** via `send(self(), {__MODULE__, msg})`. - **Function components go in domain-specific modules:** `CoreComponents` for generic UI, `RecordComponents` for records, `ScrobbleComponents` for scrobbles, `SearchComponents` for search. - **External API integrations** follow a three-module pattern: Facade (public API), API (Req HTTP client), Config (NimbleOptions).