5.8 KiB
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 frontendapps/api— Fastify APIapps/worker— asynchronous jobspackages/*— genuinely shared contracts, validation, and safe utilitiesdatabase— migrations and seedsdocs— 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. It records the completed foundation, the next bounded milestone, the overall roadmap, and verification commands.
Database Development
- Copy
.env.exampleto.envand replacechange-mewith a local-only password in both connection URLs. - Run
npm install,npm run db:up, andnpm run db:migrateto prepare the development database and Redis. - Create and migrate the isolated
pokemon_inventory_testdatabase before running integration tests. - 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:
npm run dev
This command starts healthy PostgreSQL and Redis containers, applies migrations, and runs the Fastify API, durable image worker, 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.
For a disposable local database reset, use:
npm run db:reset
npm run provision:admin
Or combine both operations with:
npm run db:reset:admin
db:reset removes the local PostgreSQL and Redis volumes, recreates healthy containers, and synchronizes the current Drizzle schema with drizzle-kit push --force. It is destructive and local-development-only. It does not modify .env.
Visual Development
Run Storybook to inspect the authoritative design tokens and mock visual fixtures without requiring API data:
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:
npm run seed:demo
The seed is non-destructive and exits without changes when the demo catalog already exists.
Browser Workflow Tests
With npm run dev running, configured local admin credentials, and demo lookup data available, run the authenticated browser workflow with:
npm run test:e2e
The workflow covers login, admin overview loading, product creation, physical inventory creation, and navigation to image management. It skips when INITIAL_ADMIN_EMAIL or INITIAL_ADMIN_PASSWORD is not configured.
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.