Skip to content

v0.0.8

Latest

Choose a tag to compare

@collectify-release collectify-release released this 28 Aug 06:05
76146a3

0.0.8 (2026-08-27)

Features

  • add enum parity CI check and model Steam Deck as Pc (38b7539)
  • add enum parity CI check and model Steam Deck as Pc (9a1982e)
  • api: bulk genres replace-set like tags, message-pinned 400 (#169) (7865843)
  • api: generic bulk PATCH endpoint (#89) (1178740)
  • api: per-type bulk field whitelists (#89) (fedf71e)
  • api: relational genres like tags; Genre entity, resolver, bulk-ready seam, exact filter, schema-only migration (#169) (6161e5a)
  • auto-backfill IGDB metadata for games after Steam import (#132) (434b80d)
  • bulk update of movies, music and games (#89) (e80f3d8)
  • cache: add DistributedCacheAdapter with fault-tolerant distributed cache access (6d7568a)
  • cache: drop SQLite LookupCache persistence via EF migration (e87f3af)
  • cache: migrate lookup contract to write-time TTL across five callers (a0da318)
  • cache: replace SQLite lookup cache with distributed cache (b2579b4)
  • cache: verify DI cache selection, singleton lifetime, and TTL validation (ca358a3)
  • capture Steam cover + last-played on import and add Steam logo to the page (b17f3c9)
  • capture Steam rich metadata (developer/publisher/year/description) on import (cbaa649)
  • client: bulk update selection, action bar and modal (#89) (25c229f)
  • client: navigate to /games after a successful Steam import (f0455a0)
  • client: relational genre chips, exact filter, bulk genres (#169) (9468c0d)
  • client: shared lookup protocol, candidate list, and camera hook (#99) (f13b252)
  • client: single media registry + shared lookup-and-prefill protocol (#98, #99) (74187ea)
  • client: single media registry keyed by MediaType (#98) (dbbd940)
  • client: type-specific detail views + rich fields (issue #88) (2d45128)
  • client: useBulkUpdate hook and BulkUpdates types (#89) (320eb12)
  • collections: add collection list sorting (0712907)
  • collections: add per-type server sort fields (4a17d74)
  • collections: add shared responsive sort controls to collection lists (1ae35d5)
  • collections: add shared server sort contract for collection lists (2de8a2b)
  • collections: add typed client sort state and request identity (415fb03)
  • collections: show sortable values on list items (c954663)
  • connect Steam & import owned games (60455f7)
  • connect Steam & import owned games (0709e34)
  • database: add provider-native PostgreSQL migration lineage (d51c139)
  • database: migrate PostgreSQL through EF Core migrations (0cd506a), closes #100
  • database: unify SQLite and PostgreSQL migrations (e0f92ef)
  • games: allow multiple digital stores per game (#91) (5881b72)
  • games: allow multiple digital stores per game (#91) (7fe4a15)
  • normalize genres to relational 1-to-many like tags (#169) (66a78a1)
  • platform-scoped IGDB matching + edit-page prefill priority (2c40335)
  • server: add rich-detail fields for movies, games, music (issue #88) (c805e7c)
  • steam: add filtered page size controls (a20a530)
  • steam: add hide-imported toggle on import page (#180) (68d1385)
  • steam: paginate owned-games preview beyond 500-cap (#181) (243ff48)
  • type-specific detail views with rich provider fields (#88) (86500eb)
  • ui: add format/platform style icons (#90) (9d1a846)
  • ui: add format/platform style icons (#90) (1016a7a)

Bug fixes

  • #169: fold genre schema into first Postgres migration, sync snapshot, regenerate PG manifests (bbf4b96)
  • address Codex bot round 3 (planner + atomic concurrent guard + rotation) (597aef4)
  • address Codex review round 2 (runner #137) (7bef753)
  • address Codex/Claude review findings on Steam import (e0e024c)
  • address Steam import review findings + add DLC parent schema hook (4a43bdd)
  • api,client: drop stale bulk selections on result change; enum overflow -> 400 (#89) (d6eecc8)
  • api,client: review round 1 — bulk tags, enum/number/currency parity, UI guards (#89) (2815719)
  • api,test: malformed bulk tags 400 + tags/unknown mixed-key and nullable-enum case tests (#89) (53c2d08)
  • api: BulkFieldBuilder.Enum must accept JSON string enum values (#89) (ffe96a8)
  • api: reject empty members in movie format filter (#97) (226d12e)
  • api: reject negative bulk hoursPlayed; pin NullableEnum overflow (#89) (d6f404d)
  • api: reject repeated query values on collection filters (#97) (013360d)
  • api: reject undefined enum values on the write boundary (#115) (15f46b2)
  • api: reject undefined enum values on the write boundary (#115) (e0fc37d)
  • api: restore list-filter wire contract in generic collection module (#97) (24363d2)
  • cache: address review round 1 findings (04e9a64)
  • cache: sanitize cache exceptions and validation guidance (091f632)
  • client: add vite-env.d.ts for TS7 CSS type declarations (2e8ad5f)
  • client: align enum display labels (cd35f9f)
  • client: align enum labels and filter controls (9467ea4)
  • client: drop removed BrowserRouter future prop for react-router v7 (e1d515c)
  • client: drop removed BrowserRouter future prop for react-router v7 (2e69a15)
  • client: expose tags and align filter counts (d3208d5)
  • client: keep react/@types/react in lockstep with react-dom 19 (81dd844)
  • client: label digital-store filter chips (9cb812b)
  • client: migrate to Tailwind v4 PostCSS plugin (71441b7)
  • client: parse offsetless added dates as UTC (e32fe48)
  • client: show only selected sort value (15e81dc)
  • database: capture PostgreSQL catalog manifests (ac5b3bc)
  • database: compare semantic PostgreSQL catalog shape (718b01f)
  • database: match Program.cs provider parsing to AddCollectifyDbContext (1eb49f2)
  • database: use valid deterministic pg_dump restrict key (be9f5ab)
  • edit-page game search filters at source when platform is known (aa6528d)
  • games: address #91 review findings (ledger remap, Down, filter, docs) (6283cb8)
  • games: backfill IGDB metadata immediately after Steam import (be84500)
  • games: canonicalize store filter names case-insensitively (#91) (e9a7a22)
  • games: canonicalize store labels in active-filter chip case-insensitively (#91) (d34df19)
  • games: expose store button pressed state for screen readers; refresh graph (#91) (d0f0ab5)
  • games: fill-only IGDB import + immediate backfill on startup (9e549dc)
  • games: hide digital-store chip when the filter mask has no defined bits (#91) (d53e51d)
  • games: resolve store labels in active-filter chip from the canonical mask (#91) (9ccb61e)
  • harden Steam import against concurrent races + reviewer findings (b9b340a)
  • heal stale/missing Steam covers on re-import (025b2c3)
  • IGDB platform-scoped search filters at the source so the PC SKU is found (a6c1554)
  • igdb: include Linux id in Pc source-filter search (#102) (5627fe9)
  • issue #88: address review findings (backfill persist, IDs, cache version) (694f783)
  • match candidates against full IGDB platform set (Codex P2) (113ce66)
  • parse KnownProxies from scalar comma value or indexed keys (a51555e)
  • partition steams callback limiter by client IP + server-side preview search (af16553)
  • platform: accept legacy Linux on game writes via JSON converter (#102) (3ae42d4)
  • platform: address Claude+Codex review findings (#102) (834fe1b)
  • platform: fold Linux into Pc, keep Mac separate (#102) (bb488a2)
  • platform: fold Linux into Pc, keep Mac separate (#102) (1626605)
  • platform: reject retired/undefined numeric platform query values (#102) (feda326)
  • platform: restore ?platform=Other filter; harden lookup + docs (#102) (5d99e76)
  • reject spoofed forwarded IPs, detach only conflicting cover, keep search filter mounted (00d55e5)
  • resolve Steam cover from storefront assets, fixes 404 for hash-pathed apps (c74d2cd)
  • revalidate match inputs after outbound work (Codex round 4) (abd8229)
  • rotate backfill sweep window to avoid head-of-queue starvation (ee76540)
  • steam: base page range on fetched page, not the hidden subset (PR #182 review) (7965bd8)
  • steam: batch large imports server-side (e9387c9)
  • steam: bound page-scoped cover repair batches (be311be)
  • steam: cap cross-page selections at 500 (fbde6cf)
  • steam: filter imported titles before pagination (9bf1a4a)
  • steam: improve filtered empty and mobile states (6aea821)
  • steam: merge, not replace, cross-page select-all (PR #182 review) (744f89a)
  • steam: persist ReleaseDate from SteamReleaseDate on import (9138ced), closes #156
  • steam: persist ReleaseDate from SteamReleaseDate on import (#156) (83ddb53)
  • steam: preserve selection when repairing covers (47f0979)
  • steam: prevent concurrent import actions (05cc006)
  • steam: repair covers across library (1deef25)
  • steam: reset page offset immediately when search term clears (PR #182 review) (b19d837)
  • steam: share configured import cap with client (63344aa)
  • ui: dedupe game platform label in detail view (fcc79a8)
  • ui: keep platform icon with platform label in game list row (afd8515)
  • ui: omit blank secondary row for unclassified games (aeb0b93)
  • use Steam's 600x900 library cover instead of the tiny logo/icon (f0d2f85)
  • verify cover winner exists before swallowing save error + document trusted-proxy setting (e37950a)
  • version IGDB cache keys so stale DTO-shape rows are never served (eb46f2f)

Refactoring

  • api: collapse collection endpoints into one generic module (#97) (1d65ec5)
  • api: hoist MovieFormat bitmask to a static readonly field (2589952)
  • cache: extract shared JSON options for lookup cache (e3d3fca)
  • client: derive all per-type tables from media registry (#98) (9bcd2a9)
  • client: drop dead null! type-token fields from registry (#149) (44fe55d)
  • client: structured byId noun/hint, drop label-sniffing (#149) (63efb07)
  • client: type-safe scan-to-form prefill channel (#99) (d47c6bd)
  • lookup: unify metadata provider interfaces into generic IMetadataProvider<T> (#94) (47135a2)
  • lookup: unify metadata provider interfaces into generic IMetadataProvider<T> (#94) (a1b3530)
  • steam: drop "what" comments in toggle-all per AGENTS.md (PR #182 review) (ce10b20)
  • steam: drop unused IConfiguration from /games handler (PR #182 review) (28c0cb8)
  • steam: remove obsolete preview cap (b104c45)

Documentation

  • #91: fix truncated-500 bold marker and stale delivery-dimension comment (61aab67)
  • add CI/CD invariants, decision records, and gate-aware ci-local (#107) (fcd0b8f)
  • add CONTRIBUTING.md and .githooks/README.md, dedupe commit rules (0762e3a)
  • cache: document distributed cache backing, Redis opt-in, and SQLite migration (40c562d)
  • data-model: genres are relational like tags; legacy CSV dropped (#169) (c5f8d3a)
  • database: correct stale EnsureCreated PostgreSQL guidance (57f22fd)
  • database: remove remaining PostgreSQL reset claims (4707c79)
  • document Steam setup (API key + PublicBaseUrl) in .env.example and README (a002720)
  • move commit-message conventions into README (00ce676)
  • platform-import: drop stale Postgres reset advice from rollout (c5fb126)

Container image

Deploy by digest — a tag can be moved, a digest cannot:

ghcr.io/mforce/collectify@sha256:442bf0f0b7fc7578237c6be8c715cb0b93132f681777ce492ee065119b7fd2fa

Machine-readable: the image.json asset on this release.
Verify the bytes came from this repo's CI before deploying:

# requires a prior `docker login` — an oci:// subject needs registry credentials.
gh attestation verify oci://ghcr.io/mforce/collectify@sha256:442bf0f0b7fc7578237c6be8c715cb0b93132f681777ce492ee065119b7fd2fa \
  --repo mforce/collectify \
  --signer-workflow mforce/collectify/.github/workflows/ci.yml \
  --source-ref refs/heads/main \
  --bundle-from-oci