Reviewed-on: #57
TehRiehl TCG Management
Self-hosted TCG collection & inventory manager (Pokémon MVP). Own your data: self-contained user accounts, a local catalog + daily market prices from TCGCSV, and a camera scanner that auto-detects cards on-device. Runs entirely on a homelab in Docker — no cloud services.
Stack
- Backend: NestJS · Prisma · PostgreSQL · BullMQ/Redis
- Frontend: React (Vite) PWA · Redux Toolkit + RTK Query · Tailwind · shadcn/ui
- Scanner: on-device OpenCV.js + perceptual-hash matching (
@tcg/scan-core) - Monorepo: pnpm workspaces · TypeScript · TDD (≥85% coverage)
- Ops: Docker · Gitea Actions CI/CD · Traefik ingress · Harbor registry
Quick start (dev)
corepack enable # activates pnpm (from packageManager)
pnpm install
# Postgres + Redis (+ api/web dev servers) in containers:
docker compose -f compose.dev.yaml up
# ...or bring up just the infra and run apps on host:
# docker compose -f compose.dev.yaml up postgres redis
# cp .env.example apps/api/.env # already present; points at localhost
pnpm --filter @tcg/api exec prisma migrate deploy
pnpm --filter @tcg/api db:seed # enables Pokémon (game id 3)
pnpm dev # api :3000, web :5173
Validate
pnpm build && pnpm typecheck && pnpm lint && pnpm test:cov
pnpm --filter @tcg/api test:e2e # needs Postgres reachable at DATABASE_URL
Deploy (homelab)
CI (.gitea/workflows/ci.yaml) builds, scans (Trivy), signs (cosign), and
pushes images to Harbor (harbor.tehriehldeal.com/tehriehltcgmanagement).
The homelab stack (Traefik-routed, external network) runs its own compose file;
compose.prod.yaml in this repo is the reference layout:
docker compose -f compose.prod.yaml up -d
Architecture notes and the full roadmap live in the plan doc. Milestones M0–M7 (scaffold, auth, ingestion, collection, PWA, scanner, polish, card-detail UX) are complete; current work is the improvement roadmap (hardening, collection UX, wishlist/analytics, scanner durability).