collectarr/collectarr-core

Canonical metadata backend for Collectarr with provider ingest, image delivery, search, and admin tooling.

Python

0

406 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

Collectarr — an open-source, local-first clean-room alternative to CLZ, looking for contributors (r/SideProject)

Hi everyone, I've been working on **Collectarr**, an open-source, local-first collection manager, and I'd love to find a few people interested in contributing, testing, or simply giving architectural/product feedback. **GitHub:**…

2

Oct 12, 2026

README

Collectarr Core

License: MIT GitHub Release Issues Made with Python FastAPI SQLAlchemy Docker

Catalog items Comics Manga Anime Books Games Board Games Movies TV Music

Shared metadata engine for Collectarr: canonical catalog, typed catalog APIs, image delivery, admin tooling, and search infrastructure.

Collectarr Core owns the shared catalog and source-neutral metadata contracts. The target product has no provider adapters or provider importers. App users search and edit canonical Catalog Items through Core. Personal library state such as owned copies, grades, notes, wishlists, and local tags stays in collectarr-app and can optionally sync through collectarr-sync.

Coordinated all-kind Catalog Item v1 cutover in progress: Core's active API, ORM models, and contracts now use Catalog Item v1 for all nine kinds. The App's active library pages use Catalog Item and Owned Copy v1 flows, but legacy App persistence and provider-dependent code are still being removed. Do not deploy this cross-repository working state or reset databases yet. The completed release will require stopping App and Core together, preserving old backups only for archival recovery, creating empty Core and App databases, running python -m app.scripts.bootstrap_schema, and rebuilding the search index. The old database and backup formats will not be supported by the final v1 baseline; create_all() will not reshape them.


✨ Features

📚 Canonical Catalog

  • Multi-media catalog covering comics, manga, anime, books, games, board games, movies, TV, and music
  • One Catalog Item per specific collectible edition/version/release, with typed contained data
  • Typed kind-aware Catalog Item/search/admin responses generated from the versioned v1 contract
  • Shared editorial metadata that complements local-first personal data in the app

🔌 Metadata Contract And Search Infrastructure

  • Versioned source-neutral catalog contracts generated from the API schemas
  • Canonical catalog writes for complete objects prepared by the app
  • Optional Meilisearch indexing for fast catalog queries and richer search previews

🖼️ Image And Storage Infrastructure

  • External image URLs by default, with optional MinIO / S3 mirroring for controlled hosting
  • Image URL normalization, cache budgeting, and origin tracking
  • Content-addressed image handling for uploaded assets and derived media variants
  • Image cache health surfaced through admin tooling instead of ad hoc scripts

🛠️ Admin And Operations

  • Admin dashboard in the Collectarr desktop app for catalog review, duplicate handling, user management, image cache stats, and audit logs
  • Role-based access with viewer / editor / admin permissions
  • OpenAPI docs at /docs for API exploration and schema-backed integration work
  • Daily-refreshable catalog badges and machine-readable contract snapshots

🧱 Database Schema

The generated schema docs stay in sync with SQLAlchemy metadata and include columns, enums, indexes, defaults, unique constraints, and cross-domain references.

Schema bootstrap

The server database is created directly from the typed SQLAlchemy models. When the schema changes, recreate the development database and run python -m app.scripts.bootstrap_schema.


🚀 Quick Start

Start the Docker stack

Copy-Item .env.example .env
docker compose up --build -d
docker compose exec api python -m app.scripts.bootstrap_schema

Run local development tooling

python -m pip install -e .[dev]
python -m ruff check .
python -m pytest

Common helper commands

.\tools\dev.ps1 start            # Start Docker stack
.\tools\dev.ps1 start -WithSync  # Start Core + collectarr-sync dev stack
.\tools\dev.ps1 schema           # Create the schema from SQLAlchemy models
.\tools\dev.ps1 test             # Run test suite
.\tools\dev.ps1 check            # Lint + type check
.\tools\dev.ps1 reset-stack      # Clean reset of containers and volumes

🧩 Extending Metadata For New Libraries

Core is the canonical source of cross-library metadata. The target app has no external metadata-provider search, credentials, provider mapping, import history, or source identifiers. It sends Core a complete Catalog Item that is ready to validate and persist.

  1. Add the typed field to the source-neutral canonical request and response schema.
  2. Keep it in the corresponding typed kind details schema and Catalog Item JSON document.
  3. Add it to Meilisearch documents when it should affect search.
  4. Export the contract bundle and update the pinned app artifact deliberately.

Core and App do not retain provider-native payloads, provenance, provider IDs, snapshots, or provider import jobs.


🌐 Local URLs


🔄 Releases

Release publishing is manual-only. The Release GitHub Actions workflow uses workflow_dispatch; pushing to main runs CI only and never auto-publishes.

Current beta release: v0.2.0

Current backend image tags:

  • ghcr.io/collectarr/collectarr-core:v0.2.0
  • ghcr.io/collectarr/collectarr-core:latest

Release docs and container tags are kept in sync with the GitHub release state before publishing.

When a releasable version is detected, the workflow publishes a GitHub Release and pushes the backend container image to ghcr.io/collectarr/collectarr-core with both the semantic version tag and latest.

The first published GHCR package defaults to private. After the first real release, open the package page in the collectarr organization and switch collectarr-core to public before expecting anonymous docker pull operations to work:

  • https://github.com/orgs/collectarr/packages/container/package/collectarr-core

For personal LAN deployment on unRAID with Docker Compose, see docs/unraid.md.


📈 Catalog Badges

The repo includes snapshot badges for total catalog items and per-kind item counts. .github/workflows/catalog-badges.yml refreshes them on a daily schedule or manual dispatch.

To switch from placeholder badges to live counts, configure:

  • COLLECTARR_BADGES_BASE_URL for the public Core base URL (e.g., COLLECTARR_BADGES_BASE_URL=http://localhost:8010)
  • COLLECTARR_BADGES_TOKEN for bearer-token access to /api/v1/admin/catalog/summary

Or, instead of a static token:

  • COLLECTARR_BADGES_EMAIL
  • COLLECTARR_BADGES_PASSWORD

The workflow logs in through /api/v1/auth/login when a bearer token is not provided.


RepoPurpose
collectarr-appFlutter client for local-first collection browsing, editing, and admin-facing UX
collectarr-syncOptional personal sync service for multi-device shelf state

🧭 Library Parity Contract

See docs/library-parity-contract.md for the cross-repository Catalog Item and Owned Copy boundaries.

🗺️ Roadmap

See docs/implementation-plan.md for the full roadmap.

Current active tracks:

  • stabilize typed-per-kind metadata storage as the canonical contract
  • deepen typed field coverage while keeping catalog and owned-copy fields separate
  • improve duplicate review using Catalog Item references
  • continue public-deployment hardening for internet-facing setups
  • keep the interactive schema explorer clearer by separating general tables from kind-specific tables
  • keep comic cover-photo recognition / scan-to-identify local-first in the app; Core only provides image search/storage primitives

Support

If Collectarr is useful to you, you can support ongoing development on Ko-fi:

Support me on Ko-fi

collectarr
collection-manager
docker
fastapi
media-metadata
meilisearch
metadata-catalog
provider-ingest
python
self-hosted
sqlalchemy

collectarr/collectarr-core

Canonical metadata backend for Collectarr with provider ingest, image delivery, search, and admin tooling.

Python

0

406 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

Collectarr — an open-source, local-first clean-room alternative to CLZ, looking for contributors (r/SideProject)

Hi everyone, I've been working on **Collectarr**, an open-source, local-first collection manager, and I'd love to find a few people interested in contributing, testing, or simply giving architectural/product feedback. **GitHub:**…

2

Oct 12, 2026

README

Collectarr Core

License: MIT GitHub Release Issues Made with Python FastAPI SQLAlchemy Docker

Catalog items Comics Manga Anime Books Games Board Games Movies TV Music

Shared metadata engine for Collectarr: canonical catalog, typed catalog APIs, image delivery, admin tooling, and search infrastructure.

Collectarr Core owns the shared catalog and source-neutral metadata contracts. The target product has no provider adapters or provider importers. App users search and edit canonical Catalog Items through Core. Personal library state such as owned copies, grades, notes, wishlists, and local tags stays in collectarr-app and can optionally sync through collectarr-sync.

Coordinated all-kind Catalog Item v1 cutover in progress: Core's active API, ORM models, and contracts now use Catalog Item v1 for all nine kinds. The App's active library pages use Catalog Item and Owned Copy v1 flows, but legacy App persistence and provider-dependent code are still being removed. Do not deploy this cross-repository working state or reset databases yet. The completed release will require stopping App and Core together, preserving old backups only for archival recovery, creating empty Core and App databases, running python -m app.scripts.bootstrap_schema, and rebuilding the search index. The old database and backup formats will not be supported by the final v1 baseline; create_all() will not reshape them.


✨ Features

📚 Canonical Catalog

  • Multi-media catalog covering comics, manga, anime, books, games, board games, movies, TV, and music
  • One Catalog Item per specific collectible edition/version/release, with typed contained data
  • Typed kind-aware Catalog Item/search/admin responses generated from the versioned v1 contract
  • Shared editorial metadata that complements local-first personal data in the app

🔌 Metadata Contract And Search Infrastructure

  • Versioned source-neutral catalog contracts generated from the API schemas
  • Canonical catalog writes for complete objects prepared by the app
  • Optional Meilisearch indexing for fast catalog queries and richer search previews

🖼️ Image And Storage Infrastructure

  • External image URLs by default, with optional MinIO / S3 mirroring for controlled hosting
  • Image URL normalization, cache budgeting, and origin tracking
  • Content-addressed image handling for uploaded assets and derived media variants
  • Image cache health surfaced through admin tooling instead of ad hoc scripts

🛠️ Admin And Operations

  • Admin dashboard in the Collectarr desktop app for catalog review, duplicate handling, user management, image cache stats, and audit logs
  • Role-based access with viewer / editor / admin permissions
  • OpenAPI docs at /docs for API exploration and schema-backed integration work
  • Daily-refreshable catalog badges and machine-readable contract snapshots

🧱 Database Schema

The generated schema docs stay in sync with SQLAlchemy metadata and include columns, enums, indexes, defaults, unique constraints, and cross-domain references.

Schema bootstrap

The server database is created directly from the typed SQLAlchemy models. When the schema changes, recreate the development database and run python -m app.scripts.bootstrap_schema.


🚀 Quick Start

Start the Docker stack

Copy-Item .env.example .env
docker compose up --build -d
docker compose exec api python -m app.scripts.bootstrap_schema

Run local development tooling

python -m pip install -e .[dev]
python -m ruff check .
python -m pytest

Common helper commands

.\tools\dev.ps1 start            # Start Docker stack
.\tools\dev.ps1 start -WithSync  # Start Core + collectarr-sync dev stack
.\tools\dev.ps1 schema           # Create the schema from SQLAlchemy models
.\tools\dev.ps1 test             # Run test suite
.\tools\dev.ps1 check            # Lint + type check
.\tools\dev.ps1 reset-stack      # Clean reset of containers and volumes

🧩 Extending Metadata For New Libraries

Core is the canonical source of cross-library metadata. The target app has no external metadata-provider search, credentials, provider mapping, import history, or source identifiers. It sends Core a complete Catalog Item that is ready to validate and persist.

  1. Add the typed field to the source-neutral canonical request and response schema.
  2. Keep it in the corresponding typed kind details schema and Catalog Item JSON document.
  3. Add it to Meilisearch documents when it should affect search.
  4. Export the contract bundle and update the pinned app artifact deliberately.

Core and App do not retain provider-native payloads, provenance, provider IDs, snapshots, or provider import jobs.


🌐 Local URLs


🔄 Releases

Release publishing is manual-only. The Release GitHub Actions workflow uses workflow_dispatch; pushing to main runs CI only and never auto-publishes.

Current beta release: v0.2.0

Current backend image tags:

  • ghcr.io/collectarr/collectarr-core:v0.2.0
  • ghcr.io/collectarr/collectarr-core:latest

Release docs and container tags are kept in sync with the GitHub release state before publishing.

When a releasable version is detected, the workflow publishes a GitHub Release and pushes the backend container image to ghcr.io/collectarr/collectarr-core with both the semantic version tag and latest.

The first published GHCR package defaults to private. After the first real release, open the package page in the collectarr organization and switch collectarr-core to public before expecting anonymous docker pull operations to work:

  • https://github.com/orgs/collectarr/packages/container/package/collectarr-core

For personal LAN deployment on unRAID with Docker Compose, see docs/unraid.md.


📈 Catalog Badges

The repo includes snapshot badges for total catalog items and per-kind item counts. .github/workflows/catalog-badges.yml refreshes them on a daily schedule or manual dispatch.

To switch from placeholder badges to live counts, configure:

  • COLLECTARR_BADGES_BASE_URL for the public Core base URL (e.g., COLLECTARR_BADGES_BASE_URL=http://localhost:8010)
  • COLLECTARR_BADGES_TOKEN for bearer-token access to /api/v1/admin/catalog/summary

Or, instead of a static token:

  • COLLECTARR_BADGES_EMAIL
  • COLLECTARR_BADGES_PASSWORD

The workflow logs in through /api/v1/auth/login when a bearer token is not provided.


RepoPurpose
collectarr-appFlutter client for local-first collection browsing, editing, and admin-facing UX
collectarr-syncOptional personal sync service for multi-device shelf state

🧭 Library Parity Contract

See docs/library-parity-contract.md for the cross-repository Catalog Item and Owned Copy boundaries.

🗺️ Roadmap

See docs/implementation-plan.md for the full roadmap.

Current active tracks:

  • stabilize typed-per-kind metadata storage as the canonical contract
  • deepen typed field coverage while keeping catalog and owned-copy fields separate
  • improve duplicate review using Catalog Item references
  • continue public-deployment hardening for internet-facing setups
  • keep the interactive schema explorer clearer by separating general tables from kind-specific tables
  • keep comic cover-photo recognition / scan-to-identify local-first in the app; Core only provides image search/storage primitives

Support

If Collectarr is useful to you, you can support ongoing development on Ko-fi:

Support me on Ko-fi

collectarr
collection-manager
docker
fastapi
media-metadata
meilisearch
metadata-catalog
provider-ingest
python
self-hosted
sqlalchemy