docs: replace Replit config/docs with README; drop Replit files
Build & Push Docker Image / build (push) Successful in 2m29s

This commit is contained in:
opencode
2026-08-03 05:43:13 +02:00
parent 53f01acb0c
commit 4648614556
7 changed files with 38 additions and 159 deletions
-35
View File
@@ -1,35 +0,0 @@
modules = ["nodejs-24", "postgresql-16"]
[deployment]
router = "application"
deploymentTarget = "autoscale"
[deployment.postBuild]
args = ["pnpm", "store", "prune"]
env = { "CI" = "true" }
[workflows]
runButton = "Project"
[agent]
stack = "PNPM_WORKSPACE"
expertMode = true
[postMerge]
path = "scripts/post-merge.sh"
timeoutMs = 20000
[[ports]]
localPort = 8080
externalPort = 80
[[ports]]
localPort = 8081
externalPort = 8081
[[ports]]
localPort = 26015
externalPort = 3000
[nix]
channel = "stable-25_05"
-5
View File
@@ -1,5 +0,0 @@
# The format of this file is identical to `.dockerignore`.
# It is used to reduce the size of deployed images to make the process of publishing faster.
# No need to store the pnpm store twice.
.local
+38 -35
View File
@@ -2,10 +2,30 @@
Community platform for listing and rating developer/productivity tools by usefulness and usability. Community platform for listing and rating developer/productivity tools by usefulness and usability.
## Run & Operate ## Stack
- `pnpm --filter @workspace/api-server run dev` — run the API server (port 8080) - pnpm workspaces, Node.js 24, TypeScript 5.9
- `pnpm --filter @workspace/toolrate run dev` — run the frontend (port 26015) - API: Express 5 + 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
## Packages
- `lib/api-spec` — OpenAPI contract (source of truth)
- `lib/api-zod` — generated Zod schemas from the spec
- `lib/api-client-react` — generated React Query hooks
- `lib/db` — Drizzle schema + DB access
- `artifacts/api-server` — Express backend
- `artifacts/toolrate` — React frontend
- `artifacts/mockup-sandbox` — component preview
## Run & develop
- `pnpm --filter @workspace/api-server run dev` — run the API server
- `pnpm --filter @workspace/toolrate run dev` — run the frontend
- `pnpm run typecheck` — full typecheck across all packages - `pnpm run typecheck` — full typecheck across all packages
- `pnpm run build` — typecheck + build 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/api-spec run codegen` — regenerate API hooks and Zod schemas from the OpenAPI spec
@@ -13,29 +33,16 @@ Community platform for listing and rating developer/productivity tools by useful
## Required env vars ## Required env vars
- `DATABASE_URL` — Postgres connection string (auto-provisioned) - `DATABASE_URL` — Postgres connection string
- `SESSION_SECRET`Session signing secret (already set) - `SESSION_SECRET`session signing secret
- `VOTER_SECRET` — secret for voter submissions
- `LOCAL_ADMIN_USERNAME` / `LOCAL_ADMIN_PASSWORD` — local admin login
## Keycloak (optional) ## Auth
Set these to enable login: - Session-based auth (not JWT), sessions stored in Postgres via connect-pg-simple.
- `KEYCLOAK_URL` — e.g. `https://auth.example.com` - Write operations (create/update/delete tools, submit ratings) require auth; reads are public.
- `KEYCLOAK_REALM` — realm name - Login via local admin user (`LOCAL_ADMIN_*`). Keycloak/OIDC support exists as an optional legacy path.
- `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 ## Where things live
@@ -45,7 +52,7 @@ Without these, the app runs in read-only mode (browsing and viewing ratings work
- `lib/api-zod/src/generated/` — generated Zod schemas (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/routes/` — Express route handlers
- `artifacts/api-server/src/middleware/auth.ts``requireAuth` middleware - `artifacts/api-server/src/middleware/auth.ts``requireAuth` middleware
- `artifacts/api-server/src/routes/auth.ts`Keycloak OIDC login/callback/logout/me - `artifacts/api-server/src/routes/auth.ts`login/logout/me
- `artifacts/toolrate/src/pages/` — frontend pages - `artifacts/toolrate/src/pages/` — frontend pages
- `artifacts/toolrate/src/components/` — shared components (layout, tool-card, category-combobox, feature-input) - `artifacts/toolrate/src/components/` — shared components (layout, tool-card, category-combobox, feature-input)
- `artifacts/toolrate/src/hooks/use-auth.ts` — auth state hook - `artifacts/toolrate/src/hooks/use-auth.ts` — auth state hook
@@ -54,9 +61,9 @@ Without these, the app runs in read-only mode (browsing and viewing ratings work
- Contract-first: OpenAPI spec → codegen → typed hooks + Zod schemas. Never hand-write fetch calls. - 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. - 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. - Write operations (create/update/delete tools, submit votes) require auth. Reads are public.
- Category and feature autocomplete are client-side filtered against live API data (no separate index). - 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. - Grafana can consume `/api/analytics/*` endpoints directly via the JSON datasource plugin.
## Product ## Product
@@ -66,16 +73,12 @@ Without these, the app runs in read-only mode (browsing and viewing ratings work
- Analytics dashboard: top tools chart, category breakdown, score distribution histograms - Analytics dashboard: top tools chart, category breakdown, score distribution histograms
- Grafana integration: all `/api/analytics/*` endpoints return clean JSON - Grafana integration: all `/api/analytics/*` endpoints return clean JSON
## User preferences ## Deployment
_Populate as you build — explicit user instructions worth remembering across sessions._ - Container image: `git.kubebase.de/admin/tool-evaluator:<tag>` (pushed by CI)
- Deployed to k3s via the `apps` repo (kustomize), served at `https://toolr.kubebase.de`
## Gotchas ## Gotchas
- Orval clears the output folder during codegen — transient HMR errors in the dev server are normal and auto-recover. - 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. - Auth uses 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
@@ -1,32 +0,0 @@
kind = "api"
previewPath = "/api" # TODO - should be excluded from preview in the first place
title = "API Server"
version = "1.0.0"
id = "3B4_FFSkEVBkAeYMFRJ2e"
[[services]]
localPort = 8080
name = "API Server"
paths = ["/api"]
[services.development]
run = "pnpm --filter @workspace/api-server run dev"
[services.production]
[services.production.build]
args = ["pnpm", "--filter", "@workspace/api-server", "run", "build"]
[services.production.build.env]
NODE_ENV = "production"
[services.production.run]
# we don't run through pnpm to make startup faster in production
args = ["node", "--enable-source-maps", "artifacts/api-server/dist/index.mjs"]
[services.production.run.env]
PORT = "8080"
NODE_ENV = "production"
[services.production.health.startup]
path = "/api/healthz"
@@ -1,17 +0,0 @@
kind = "design"
previewPath = "/__mockup"
title = "Canvas"
version = "1.0.0"
id = "XegfDyZt7HqfW2Bb8Ghoy"
[[services]]
localPort = 8081
name = "Component Preview Server"
paths = ["/__mockup"]
[services.env]
PORT = "8081"
BASE_PATH = "/__mockup"
[services.development]
run = "pnpm --filter @workspace/mockup-sandbox run dev"
@@ -1,31 +0,0 @@
kind = "web"
previewPath = "/"
title = "ToolRate — Tool-Bewertungsplattform"
version = "1.0.0"
id = "artifacts/toolrate"
router = "path"
[[integratedSkills]]
name = "react-vite"
version = "1.0.0"
[[services]]
name = "web"
paths = [ "/" ]
localPort = 26015
[services.development]
run = "pnpm --filter @workspace/toolrate run dev"
[services.production]
build = [ "pnpm", "--filter", "@workspace/toolrate", "run", "build" ]
publicDir = "artifacts/toolrate/dist/public"
serve = "static"
[[services.production.rewrites]]
from = "/*"
to = "/index.html"
[services.env]
PORT = "26015"
BASE_PATH = "/"
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
set -e
pnpm install --frozen-lockfile
pnpm --filter db push