Files
tool-evaluator/replit.md
T
cheffe01 7abb048edc Add user authentication and dynamic feature/category inputs
Implement Keycloak authentication, protected routes, and add combobox and autocomplete components for tool categories and features.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 776963d0-f75d-42e2-a57b-cc36bdff8495
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 0b145113-c016-4f54-b000-13bd3b0ba8f0
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0683fb79-a27c-485c-9333-5f4b288c4567/776963d0-f75d-42e2-a57b-cc36bdff8495/z4uWN6A
Replit-Helium-Checkpoint-Created: true
2026-05-25 13:20:15 +00:00

3.7 KiB

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.tsrequireAuth 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