diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..971ac8e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,58 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Pokemon TCG card database and inventory management app. Users search cards, track market prices, and manage their collections. Closed beta. + +## Commands + +```bash +npm run dev # Start dev server (binds 0.0.0.0:4321) +npm run build # Production build → ./dist/ +npm run preview # Preview production build +``` + +No test framework or linter is configured. + +Utility scripts in `scripts/` are run directly with `tsx` (e.g., `npx tsx scripts/reindex.ts`). + +## Tech Stack + +- **Astro 5** (SSR mode, Node.js standalone adapter) +- **PostgreSQL** via Drizzle ORM (schema in `pokemon` namespace, snake_case DB columns) +- **Typesense** for full-text card search +- **Clerk** for authentication +- **HTMX** for dynamic interactions (no SPA framework) +- **Bootstrap 5** with custom SCSS overrides, dark theme +- **Chart.js** for price history charts + +## Architecture + +### Data Flow + +TCGPlayer source data → `tcg_cards` → denormalized `cards` (per variant) → `skus` (per condition/language) → `price_history` / `sales_history`. User collections stored in `inventory` table linked to Clerk userId. + +PostgreSQL is source of truth. Typesense mirrors card/sku/inventory data for search. Both must be kept in sync — see `src/pages/api/inventory.ts` for the sync pattern (write to PG, then upsert/delete in Typesense). + +### Key Directories + +- `src/pages/` — Astro routes and API endpoints +- `src/pages/partials/` — HTMX partial responses (HTML fragments returned to `hx-post` targets) +- `src/pages/api/` — JSON/file API endpoints (`upload.ts` for CSV, `inventory.ts` for CRUD) +- `src/components/` — Reusable `.astro` components +- `src/db/` — Drizzle schema (`schema.ts`), relations (`relations.ts`), DB connection (`index.ts`), Typesense client (`typesense.ts`) +- `scripts/` — Data ingestion and indexing utilities (not part of the app runtime) + +### Authentication + +Clerk middleware in `src/middleware.ts` protects routes via `createRouteMatcher`. Auth context accessed via `Astro.locals.auth()` in pages/API routes. + +### Database Schema + +Drizzle config uses `casing: 'snake_case'` — define schema fields in camelCase, they map to snake_case columns automatically. Migrations live in `./drizzle/`. Schema is scoped to the `pokemon` PostgreSQL schema. + +### Frontend Patterns + +Pages use HTMX for interactivity — forms POST to `/partials/*` endpoints that return HTML fragments. No client-side routing. View Transitions API enabled for page navigation animations. Card modals and inventory forms are HTMX-driven with `hx-post`, `hx-target`, and `hx-swap` attributes.