Everything below (and in this repo) is unapologetically vibecoded. Expect vibes, not guarantees. Proceed with good humor and version control.
Contributions are welcome. Open a pull request for fixes, features, or docs. Not sure where to start? Open an issue and we'll chat. Small improvements are great.
Found a bug or have an idea? Open an issue. Include steps to reproduce, expected vs. actual behavior. Screenshots or logs help.
Fork, branch, and submit a focused PR. Add or update tests and docs as needed. Explain the "why" and link related issues. Make sure checks pass.
Be kind. Be clear. Assume good intent. Keep feedback constructive.
A self-hosted, full-stack Pokémon TCG collection manager for cards, sealed products, binders, analytics, scanning, and multi-user collections.
- Features
- Quick Start
- Environment Variables
- Architecture
- Tech Stack
- Documentation
- Configuration Reference
- Updating
- Support
- License
- Add cards with quantity, condition, variant, and purchase price
- Variants are now limited to
Normal,Holo,Reverse Holo, andFirst Edition - Card rarity is read-only from TCGdex and displayed separately from variant
- Track German, English, and Chinese cards separately
- Manually create custom cards not present in TCGdex
- Search the locally cached card database by name, set, type, rarity, HP, artist, and more
- Short-code search like
PFL 001 - Smart scanner with Gemini-powered recognition
- Two-step scanner matching: number ranking first, visual verification second
- Scanner strips suffixes like
ex/GX/VSTARfor broader matching - Card modal auto-preselects a likely variant from TCGdex variant flags
- Set overview with completion progress and per-set checklist
- Virtual binders for collection and checklist views
- Wishlist with Telegram price alerts
- Cardmarket EUR pricing and TCGPlayer USD pricing via TCGdex
- Price history charts and portfolio snapshots
- Dashboard, duplicates, top movers, rarity stats, and investment tracker
- Sealed product tracking with realized and unrealized P&L
- Single-user mode: no login required, auto-auth as admin
- Multi-user mode: JWT login, admin/trainer roles, separate user data
- Per-user settings for language, currency, Telegram keys, and Gemini key
- Force password change support on first login
- Profile avatar and profile name editing
- Cascade deletion of user-owned data
- Leaderboard, trainer comparison, and achievements in multi-user mode
- View other trainers' collections from the Leaderboard
- Community section in Settings with GitHub contributors and Ko-fi supporters
- Compact portal navigation with 6 primary home items and grouped tab navigation
- German, English, and Chinese UI
- 9 Pokemon-type color themes: Default, Fire, Water, Grass, Electric, Psychic, Dragon, Dark, Fairy
- CSV and PDF export
- Admin-only sync endpoints and scheduler controls
- Backup and restore, including selective backup groups for collection, users, cards, products, system data, and images
- Backend image proxy/cache for cards and sets
git clone https://github.com/Git-Romer/pokecollector.git
cd pokecollectorCreate a .env file in the project root:
POSTGRES_PASSWORD=your_secure_password
JWT_SECRET_KEY=some_long_random_string
# Optional
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your_admin_password
GEMINI_API_KEY=your_gemini_key
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id
TCGDEX_SYNC_LANGUAGES=en,de
PUBLIC_MODE=false
CORS_ORIGINS=https://yourdomain.comdocker compose up -d| Service | URL |
|---|---|
| App | http://localhost:3000 |
| API docs | http://localhost:8000/docs |
On first launch, trigger a sync from the app to populate sets and cards from TCGdex.
- In single-user mode, login is skipped and the app auto-authenticates as admin
- In multi-user mode, use the admin account created from
ADMIN_USERNAME/ADMIN_PASSWORD - If
ADMIN_PASSWORDis omitted, a random password may be logged during bootstrap
| Variable | Description | Default |
|---|---|---|
POSTGRES_PASSWORD |
PostgreSQL database password | changeme |
| Variable | Description | Default |
|---|---|---|
JWT_SECRET_KEY |
Secret used to sign JWT tokens; without it, sessions are not stable across restarts | Random per restart |
| Variable | Description | Default |
|---|---|---|
ADMIN_USERNAME |
Username for the bootstrap admin account | admin |
ADMIN_PASSWORD |
Password for the bootstrap admin account | Random, optionally logged |
GEMINI_API_KEY |
Initial Gemini key for the admin user; other users configure their own key in Settings | (empty) |
TELEGRAM_BOT_TOKEN |
Initial Telegram bot token for the admin user | (empty) |
TELEGRAM_CHAT_ID |
Initial Telegram chat ID for the admin user | (empty) |
TCGDEX_SYNC_LANGUAGES |
Initial admin default for TCGdex set/card sync languages on first launch only. After bootstrap, the DB setting in Settings is authoritative. Allowed values: en, de, en,de |
en,de |
ADMIN_BOOTSTRAP_LOG |
Whether bootstrap credentials may be logged on first start | true |
PUBLIC_MODE |
Enable SEO meta tags, Open Graph, and allow search engine indexing. Default blocks all crawlers. Requires rebuild. | false |
CORS_ORIGINS |
Comma-separated list of allowed origins for CORS. If empty, allows all origins. Set to your domain for production (e.g. https://pokecollector.romerg.de). |
(all) |
pokecollector/
├── backend/ # FastAPI + SQLAlchemy + PostgreSQL
│ ├── api/ # Feature routers
│ ├── services/ # Auth, sync, scheduler, Telegram, TCGdex integration
│ ├── models.py # ORM models
│ ├── schemas.py # Pydantic schemas
│ └── database.py # DB init and idempotent migrations
├── frontend/ # React 18 + Vite + Tailwind CSS
│ └── src/
│ ├── pages/
│ ├── components/
│ ├── contexts/
│ ├── hooks/
│ ├── i18n/
│ └── api/
└── docker-compose.yml
The old nested pokemon-tcg-collection/ layout is no longer used.
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, TanStack Query |
| Backend | Python 3.11, FastAPI, SQLAlchemy, APScheduler, Pydantic |
| Database | PostgreSQL 15 |
| Card Data | TCGdex |
| AI Scanner | Google Gemini 2.5 Flash |
| Deploy | Docker + Docker Compose |
| Doc | Description |
|---|---|
docs/ARCHITECTURE.md |
System structure, data flow, contexts, settings model |
docs/BACKEND.md |
API routes, models, settings scoping, backup behavior |
docs/FRONTEND.md |
Routes, pages, components, contexts, theming, i18n |
All settings are persisted in the database and edited in the Settings UI.
| Setting | Default | Notes |
|---|---|---|
| Language | de |
de, en, zh |
| Currency | EUR |
Per-user |
| Primary Price | trend |
Per-user |
| Multi-User Mode | false |
Admin-only toggle |
| Theme | default |
Stored in browser local storage |
| Price Sync Interval | 30 minutes |
Admin-only |
| Full Sync Interval | 5 days |
Admin-only |
Back up the database before updating:
docker compose exec postgres pg_dump -U pokemon pokemon_tcg > backup_$(date +%Y%m%d).sqlThen update:
git pull
docker compose up -d --buildDatabase migrations run automatically on startup.
If you want to support the project, use Ko-fi:
Supporters listed through Ko-fi can appear in the in-app Community section.
