Documentation
Changelog¶
All notable changes to CatalogueCanvas.
The format is based on Keep a Changelog.
Released versions are tagged (see v* tags and the published ghcr.io image); earlier
pre-release entries are grouped by date.
[0.2.1] - 2026-07-29¶
Added¶
CC_PREVIEW_MAX_EDGE(default2500) caps the longest edge of a generated SVG preview. Previews were rendered at a blindscale=2.5multiplier, so an 1870×2645 plotter SVG rasterised to 4675×6612 — cost grows with the square of the output size and was unbounded. Capping the longest edge cut a representative dense SVG from 7.2s to 2.2s while preserving the aspect ratio, and never upscales inputs already below the cap. Set it to0to disable. Applies to new ingests; existing previews are unchanged.
Fixed¶
- Uploading a ZIP no longer stalls the whole server.
POST /api/items/uploadran the ingest, including SVG rasterisation, directly on the event loop, so a single dense file blocked every other request on the worker until it finished. Behind a reverse proxy this surfaced as a504on the upload and on unrelatedGET /api/items,/api/portfoliosand/api/collections, while the app's own log showed only200 OK. Ingest now runs in a threadpool.
Changed¶
- Dependency bumps merged from Dependabot:
fastapi(>=0.139.2 → >=0.140.13),uvicorn[standard](>=0.51.0 → >=0.52.0),psutil(>=6.0.0 → >=7.2.2),jsdom(29.1.1 → 30.0.1, dev), and the npm minor/patch group covering@types/node,eslintandglobals(dev). Workflow action pins moved todocker/login-actionv4.6.0 andossf/scorecard-actionv2.4.4.
[0.2.0] - 2026-07-28¶
Added¶
- Anonymous, opt-in telemetry via PostHog (EU region). Nothing is sent by default. A one-time install ping fires on first boot only when
CC_INSTALL_TRACKING=1, and a weekly usage-stats ping is toggled under Settings → Usage statistics and defaults to off. Both are keyed by a random per-instance ID stored under the data volume; no hostname, IP, paths, or catalogue content is ever sent. Operators can point at their own PostHog withCC_POSTHOG_HOST/CC_POSTHOG_KEY. See Privacy for the fields, payload examples, and how to switch both off.
Changed¶
- Added a dev-only
web-devservice todocker-compose.ymlfor the web toolchain (install, lint, type-check, test). The shipped image is a production build with no devDependencies, so it cannot run these; the new service is pinned to the samenode:22-slimdigest as the Dockerfile's build stage and sits behind thedevcompose profile, leavingdocker compose upunchanged.
Security¶
- Migrated
react-router-dom7.18.1 →react-router8.3.0, fixing a CSRF bypass in RSC code paths (GHSA-qwww-vcr4-c8h2). Thereact-router-dompackage no longer exists as of v8 — its exports moved intoreact-routeritself, so this is an import-path rename across the web app with no API changes. The advisory only affects apps using the unstable RSC APIs, which this app does not. - Bumped
brace-expansion(dev-only transitive, via eslint/minimatch) to 5.0.8, fixing a denial of service via unbounded expansion length (GHSA-mh99-v99m-4gvg).
[0.1.6] - 2026-07-22¶
Added¶
- Portfolio index entries are now links. Each thumbnail in the "Works" index jumps to that item's section (
#work-<id>), in both the live deck and the static zip export.
Changed¶
- Scroll-layout portfolios read as one continuous page: section rules are dropped everywhere except under the cover, which gains breathing room below it, and the index no longer repeats its heading or leaves a gap between pages.
scripts/coverage-to-codacy.shaccepts--auto/--yes/--skip-regenerateso it can run unattended, and fetches a version-pinned Codacy reporter binary verified against its published SHA-512 checksum instead of piping a rolling installer script straight intobash.- Web coverage thresholds now sit just below the measured level (lines 75, statements 72, functions 60, branches 60). The previous
branches: 80floor was above actual coverage and failed the coverage run outright, while the lines/statements floors of 30 were far below it. - Dependency bumps:
codeql-actioninit/analyze,astral-sh/setup-uv,coverage,fastapi, React/Vite/typescript-eslint minor-patch group, and@testing-library/jest-dom(major, 6→7).
Fixed¶
- Docker builds no longer report success when they fail. A
;before a trailingtrueended the&&chain in the dependency-install step, sotrueset the step's exit status and a failinguv sync --frozenorapk delstill produced an image. The cache-purge failure is now suppressed with a braced{ ...; || true; }group, which scopes the guard to that one command; a bare trailing|| truewould have applied to the whole chain and masked the same failures. - Codacy token parsing no longer strips spaces from inside the token value; only surrounding whitespace and quotes are trimmed.
Security¶
- Bumped
brace-expansion(transitive, via eslint/minimatch) to 5.0.7, fixing a ReDoS vulnerability (GHSA-3jxr-9vmj-r5cp).
[0.1.5] - 2026-07-18¶
Added¶
- Configurable LLM response wait timeout, set from Settings (default 90s) and applied to both single-item and batch description generation. The setting notes that for local LLM instances (Ollama, LM Studio) the right value is found by experience, since slow hardware or a cold model load can exceed 90 seconds.
- "View items" link on each collection that opens the main Items page filtered to that collection (via a
?collection=URL parameter), with a clearable filter chip showing the active collection.
Changed¶
- Item page now shows only an item's selected collections as chips by default, with an "Edit" button that reveals the full collection checklist and collapses back after saving. Previously every available collection was listed for every item, which grew unwieldy as collections accumulated.
- Reworded the update-check help text in Settings for clarity.
Fixed¶
- Prev/next navigation arrows on the item page no longer clip at the glyph tips; their horizontal offset is nudged inward.
[0.1.4] - 2026-07-15¶
Added¶
- Item images open at full size. Clicking the preview on an item page opens a lightbox that fits the image to the screen, toggles to 1:1 on click, and pans by dragging. Previews were already stored at full resolution, so no new assets are generated. Arrow-key item navigation is suspended while the lightbox is open.
- Portfolio layout option, chosen per portfolio and independent of the theme:
slide(the existing full-height deck, printable to PDF at 1920×1080) orscroll(a continuous one-page site with no page breaks and no print button). Any of the four themes can be published either way. Applies to the live portfolio and the static zip export. Existing portfolios default toslide.
Fixed¶
- The lightbox now fits the image to the screen at all times. Clicking to zoom to 1:1 opened large images past the edge of the viewport, so the zoom and drag-to-pan behaviour is gone.
- "Preview deck" and the portfolio list's "View" button now carry the share token. Both linked to the untokenized URL, which returns 404 for a gated portfolio.
[0.1.3] - 2026-07-11¶
Added¶
- Opt-in update check. An admin-only
/api/versionendpoint queries GitHub for the latest release (weekly throttle, no network unless enabled) and the footer surfaces when a newer version is available. Configurable from Settings.
Fixed¶
- LLM descriptions are now stored identically whether generated for a single item or in batch. Both paths use a shared
describeResultToNotehelper, so the full summary and bullet list are saved to the note instead of only the summary in the batch flow.
[0.1.2] - 2026-07-10¶
Fixed¶
- LLM description pipeline: preview images (stored as WebP) were sent to the vision endpoint under a hardcoded
data:image/jpeglabel, so the bytes never matched the declared MIME type. This worked only on lenient runtimes and failed withHTTP 400 Failed to load image or audio fileon LM Studio versions that trust the declared type (which accepts only jpeg/png). Previews are now transcoded to real JPEG before the request, and undecodable images raise a clear error. - Footer now displays the correct app version.
web/package.jsonversion was left at the default0.0.0, which Vite injects as__APP_VERSION__and the footer renders; bumped it to0.1.1to match the release.
[0.1.1] - 2026-07-08¶
Security¶
- Bumped dependencies via Dependabot (consolidated): raised Python floors (fastapi 0.139.0, uvicorn 0.51.0, markdown 3.10.2, coverage 7.15.0, respx 0.23.1), web devDependencies (@types/node 26.1.1, @vitest/coverage-v8 4.1.10, typescript-eslint 8.63.0, vite 8.1.3, vitest 4.1.10), and pinned GitHub Actions (docker setup-buildx 4.2.0, docker login 4.4.0, docker build-push 7.3.0, codeql-action 4.37.0, astral-sh/setup-uv 8.3.2).
- Earlier Dependabot batch: pinned GitHub Actions (checkout, upload-artifact, docker login/setup-buildx/metadata) and raised Python (fastapi, uvicorn, cairosvg, passlib, python-multipart) and web npm floors.
[0.1.0] - 2026-06-30¶
Added¶
- Token-secured shared portfolio links: opt-in per-portfolio share token gates the public deck so a link without the token returns a 404; a valid token sets a cookie so the recipient can revisit without re-pasting it. Admins can require, regenerate, disable, and copy the link from the portfolio editor. Live server only — static exports remain unlisted.
2026-06-20¶
Added¶
- CSV batch metadata editing: export catalogue metadata to CSV, re-import edits with a preview of pending changes, and per-import lz4 backups.
Changed¶
- Updated repository links and footer.
Security¶
- Hardened Docker secret defaults.
- Hardened request throttling, archive downloads, and exports.
- Added revocable sessions and CSRF protection.
- Hardened the secret key handling and gated storage access.
2026-06-19¶
Added¶
- Floating activity tray that tracks long-running background work (uploads, batch and single-item LLM descriptions) across page navigation.
Changed¶
- Cookies default to insecure over plain HTTP for LAN/local testing.
- Updated README.
2026-06-18¶
Added¶
- Multi-user mode with admin and read-only reader roles.
- Username-based login, reader downloads, an HTML 404 page, and a diagnostics endpoint/report.
- Full-text metadata search across title, notes, tags, and flattened item metadata.
- Per-item JSON-LD export (schema.org / Dublin Core) with the persistent item ID embedded for FAIR-style harvesting.
- Batch LLM description button with per-batch API key prompt.
Changed¶
- Session signing key is now generated at the Docker entrypoint; LLM API URL is parsed and completed as needed.
- Raised the LLM request timeout to 90 seconds.
- Strip LLM reasoning from generated descriptions.
Fixed¶
- lz4 raw file download served correctly.
2026-06-16¶
Added¶
- Media folder support.
2026-06-15¶
Added¶
- Bulk item actions and a printable slide deck.
- Slug generation, LLM Markdown fallback, item navigation, and an appearance API.
- Icon mark, login logo, and collapsible item filters.
- Multi-library storage support for keeping assets on different disks or paths.
- Secrets implementation, footer, and license.
Security¶
- Initial security hardening from an audit.
2026-06-14¶
Added¶
- Web server backend with database, Docker support, and a settings page.
- Upload queue, LLM toggle, Markdown deck, and bind-mount support.
- Grid redesign and theming.
Changed¶
- Moved the legacy static-site pipeline to
legacy/.
Fixed¶
- Thumbnail cropping for all aspect ratios.
2026-06-13¶
Added¶
- Initial repository scaffold with configuration examples.
- ZIP ingestion with generated item IDs and a multi-image preview notice.
- LLM item description generator.
catalogcanvasCLI with an init wizard.- Static site build command.
- Project README and usage docs.