# Pokémon Inventory & Sales Reference Catalog A personal Pokémon inventory and sales reference catalog for documenting owned Pokémon products, comparing market pricing from supported providers, and presenting public asking prices. ## Scope This is a catalog and sales-reference application, not an e-commerce platform. The application supports: - Pokémon trading cards - Pokémon merchandise - Sealed products - Accessories - Pokémon Worlds / Pokémon Center merchandise - Other Pokémon-related products The public site communicates what is available, what the market suggests it is worth, and what the seller is asking. Transactions occur outside the application. ## Core domain model `Product → Inventory Item → Listing → Sale` - **Product:** what an item is. - **Inventory Item:** an individual physical copy owned by the seller. - **Listing:** the current public offer for an inventory item. - **Sale:** a manual record of an external transaction. Products remain in the database after inventory is sold. ## Technology - Vue 3 + Vite - Modern JavaScript / latest ECMAScript - Vue Router - Pinia where justified - Node.js + Fastify - PostgreSQL + Drizzle ORM - Redis + BullMQ - REST API under `/api/v1` - Docker + Docker Compose - GitHub Actions - PostgreSQL-backed search behind a `SearchService` - Pluggable image storage and pricing-provider adapters - Automated unit, integration, component, E2E, and accessibility tests - WCAG 2.2 AA target TypeScript is not used unless a documented technical justification establishes a concrete benefit that cannot reasonably be achieved with modern JavaScript. ## Repository layout - `apps/web` — Vue frontend - `apps/api` — Fastify API - `apps/worker` — asynchronous jobs - `packages/*` — genuinely shared contracts, validation, and safe utilities - `database` — migrations and seeds - `docs` — source-of-truth project documentation - `.github` — Copilot instructions and CI Read `AGENTS.md` and `.github/copilot-instructions.md` before implementing features. ## Implementation Status Start future work from [docs/IMPLEMENTATION-STATUS.md](docs/IMPLEMENTATION-STATUS.md). It records the completed foundation, the next bounded milestone, the overall roadmap, and verification commands. ## Database Development 1. Copy `.env.example` to `.env` and replace `change-me` with a local-only password in both connection URLs. 2. Run `npm install`, `npm run db:up`, and `npm run db:migrate` to prepare the development database and Redis. 3. Create and migrate the isolated `pokemon_inventory_test` database before running integration tests. 4. Run `TEST_DATABASE_URL='postgresql://...' TEST_REDIS_URL='redis://...' npm run test:integration`. Integration tests reject database names not ending in `_test` and truncate their tables before each test. The Redis limiter test uses a unique temporary key prefix and does not modify application session data. ## Local Development After creating `.env` and setting the required local SMTP and MFA values, start the complete development stack from the repository root with: ```sh npm run dev ``` This command starts healthy PostgreSQL and Redis containers, applies migrations, and runs the Fastify API and Vue/Vite web app together. Open `http://localhost:5173/` in a browser. The Vite server proxies `/api` requests to the API on port `3000`. The command does not provision an administrator automatically. Run `npm run provision:admin` once after setting the initial administrator variables in `.env` when admin access is needed. Stop the application processes with `Ctrl+C`; stop the containers separately with `npm run db:down` when they are no longer needed. ## Visual Development Run Storybook to inspect the authoritative design tokens and mock visual fixtures without requiring API data: ```sh npm run storybook ``` Open `http://localhost:6006/`. Use the Storybook theme toolbar to switch between light and dark themes. The accessibility addon is enabled for component review. The fixture showcase is intentionally mock-only and is not part of the production router. Seed representative API-backed catalog data for browser testing with: ```sh npm run seed:demo ``` The seed is non-destructive and exits without changes when the demo catalog already exists. ## Initial Administrator After the development database is migrated, set `INITIAL_ADMIN_EMAIL`, `INITIAL_ADMIN_PASSWORD`, and `INITIAL_SELLER_NAME` in your local `.env`, then run `npm run provision:admin` once. The command creates the only initial administrator and linked Seller; it refuses to run after any User exists. ## Password Recovery Set `SMTP_URL`, `SMTP_FROM`, and `PASSWORD_RESET_URL` in the local `.env` before starting the API. Password reset tokens are delivered only through SMTP, expire after one hour, are stored as hashes, and are single use. ## MFA Secret Protection Set `MFA_ENCRYPTION_KEY` to a base64-encoded 32-byte key before starting the API. Generate one with `openssl rand -base64 32`; keep it in secret management and retain it for as long as enrolled MFA methods must remain readable.