# ToolRate Community platform for listing and rating developer/productivity tools by usefulness and usability. ## Run & Operate - `pnpm --filter @workspace/api-server run dev` — run the API server (port 8080) - `pnpm --filter @workspace/toolrate run dev` — run the frontend (port 26015) - `pnpm run typecheck` — full typecheck across all packages - `pnpm run build` — typecheck + build all packages - `pnpm --filter @workspace/api-spec run codegen` — regenerate API hooks and Zod schemas from the OpenAPI spec - `pnpm --filter @workspace/db run push` — push DB schema changes (dev only) ## Required env vars - `DATABASE_URL` — Postgres connection string (auto-provisioned) - `SESSION_SECRET` — Session signing secret (already set) ## Keycloak (optional) Set these to enable login: - `KEYCLOAK_URL` — e.g. `https://auth.example.com` - `KEYCLOAK_REALM` — realm name - `KEYCLOAK_CLIENT_ID` — client ID - `KEYCLOAK_CLIENT_SECRET` — client secret - `APP_URL` — public base URL for OAuth callback (optional, auto-detected if omitted) Without these, the app runs in read-only mode (browsing and viewing ratings works, submitting tools/ratings requires login). ## Stack - pnpm workspaces, Node.js 24, TypeScript 5.9 - API: Express 5 + openid-client (Keycloak OIDC) + express-session + connect-pg-simple - DB: PostgreSQL + Drizzle ORM - Validation: Zod (`zod/v4`), `drizzle-zod` - API codegen: Orval (from OpenAPI spec) - Build: esbuild (CJS bundle) - Frontend: React 19 + Vite + TanStack Query + wouter + shadcn/ui + recharts ## Where things live - `lib/api-spec/openapi.yaml` — source of truth for the API contract - `lib/db/src/schema/` — Drizzle table definitions (`tools.ts`, `ratings.ts`) - `lib/api-client-react/src/generated/` — generated React Query hooks (do not edit) - `lib/api-zod/src/generated/` — generated Zod schemas (do not edit) - `artifacts/api-server/src/routes/` — Express route handlers - `artifacts/api-server/src/middleware/auth.ts` — `requireAuth` middleware - `artifacts/api-server/src/routes/auth.ts` — Keycloak OIDC login/callback/logout/me - `artifacts/toolrate/src/pages/` — frontend pages - `artifacts/toolrate/src/components/` — shared components (layout, tool-card, category-combobox, feature-input) - `artifacts/toolrate/src/hooks/use-auth.ts` — auth state hook ## Architecture decisions - Contract-first: OpenAPI spec → codegen → typed hooks + Zod schemas. Never hand-write fetch calls. - Session-based auth (not JWT) — sessions stored in Postgres via connect-pg-simple. - Write operations (create/update/delete tools, submit ratings) require auth. Reads are public. - Category and feature autocomplete are client-side filtered against live API data (no separate index). - Grafana can consume `/api/analytics/*` endpoints directly via JSON datasource plugin. ## Product - Browse and search tools by category, with ratings (usefulness 1-5 + usability 1-5) - Submit new tools with features and tags - Rate tools with comment and reviewer name - Analytics dashboard: top tools chart, category breakdown, score distribution histograms - Grafana integration: all `/api/analytics/*` endpoints return clean JSON ## User preferences _Populate as you build — explicit user instructions worth remembering across sessions._ ## Gotchas - Orval clears the output folder during codegen — transient HMR errors in the dev server are normal and auto-recover. - Auth routes use PKCE — the code_verifier is stored in the session, not in-memory state. - `trust proxy: 1` is set on Express so that session cookies work correctly behind Replit's reverse proxy. ## Pointers - See the `pnpm-workspace` skill for workspace structure, TypeScript setup, and package details