My Secret Santa
Organize your Secret Santa gift exchange with private groups and anonymous messaging
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A small chat-platform API built with Bun, Effect (HttpApi), and
Drizzle ORM over PGlite (an embedded Postgres), plus a TanStack
Start (React) frontend in web/. See web/README.md
for frontend-specific docs.
bun run start runs without hot reload. The API docs (Swagger) are served at
http://localhost:3000/docs. The database is a local PGlite data directory
(DB_PATH, unset = in-memory), created and migrated automatically on startup.查看完整 README ↗A small chat-platform API built with Bun, Effect (HttpApi), and
Drizzle ORM over PGlite (an embedded Postgres), plus a TanStack
Start (React) frontend in web/. See web/README.md
for frontend-specific docs.
bun install
bun run dev # backend on http://localhost:3000 (--hot reload)
bun run start runs without hot reload. The API docs (Swagger) are served at
http://localhost:3000/docs. The database is a local PGlite data directory
(DB_PATH, unset = in-memory), created and migrated automatically on startup.
Uploaded audio attachments are transcoded via the ffmpeg/ffprobe binaries
(see src/AudioProcessing.ts) rather than a bundled
npm package, so they need to be installed and on PATH to run the backend or
its tests outside Docker (the docker-compose.yml/Dockerfile image installs
them automatically).
GET /health (liveness — the process is up) and GET /ready (readiness —
the DB, and Redis when REDIS_URL is set, are reachable) are unauthenticated
ops endpoints for orchestrators/load balancers; see
src/Health.ts. They aren't part of ChatApi, so they
don't appear in the Swagger docs or the generated frontend client.
cp .env.example .env # then fill in JWT_SECRET/POSTGRES_PASSWORD/REDIS_PASSWORD
docker compose up --build
docker-compose.yml refuses to start unless JWT_SECRET, POSTGRES_PASSWORD,
and REDIS_PASSWORD are set (no insecure fallback defaults — see
.env.example); docker compose reads them from a .env
file in the repo root automatically.
Starts a real Postgres and Redis container plus the backend (built from the
root Dockerfile) connected to both via DATABASE_URL/
REDIS_URL — see docker-compose.yml. A db-upgrade
service runs first and pg_upgrades the pgdata volume in place if it's still
on a previous Postgres major version (a no-op otherwise) — see the comments
above that service in docker-compose.yml. A db-migrate service then
applies Drizzle migrations before the app boots (see issue #178 — migrations
are no longer run automatically on startup when DATABASE_URL is set, to
avoid race conditions in multi-replica Kubernetes deployments; bun run db:migrate can also be run standalone). The backend is on
http://localhost:3000; set DATABASE_URL/REDIS_URL yourself (see
.env.example) to point bun run dev/start at that same
Postgres/Redis instead of the in-process defaults (embedded PGlite, and an
in-memory realtime fan-out that only works for a single instance — see
src/PubSub.ts). When running directly with DATABASE_URL,
remember to run bun run db:migrate first.
Two independent suites:
bun test ./srcBun's built-in test runner. src/users.test.ts exercises the
Effect HttpApi in-process (no network): every test gets a fresh in-memory
PGlite database (real Postgres semantics, no server to run) with the
Drizzle migrations applied and a deterministic JWT_SECRET, so tests are
fully isolated and don't depend on a local .env. Realtime delivery uses the
in-memory PubSub fallback everywhere except
src/RealtimePubSub.integration.test.ts,
which needs a real Redis at REDIS_URL and skips itself when one isn't
configured.
cd web && bun run test:e2ePlaywright (Chromium) drives the real frontend against
the real backend. The webServer block in
web/playwright.config.ts boots both servers for
the run — the backend (bun run start, with a test JWT_SECRET) and the Vite
dev server — so a single command spins up everything. First-time setup needs the
browser binary:
cd web
bunx playwright install --with-deps chromium
bun run test:e2e
On CI, failed runs retry twice and capture traces (trace: "on-first-retry").
Several files are generated rather than hand-written — do not edit them directly; re-run the relevant command instead. All are gitignored.
| Artifact | Command | What it does |
|---|---|---|
openapi.json | bun run gen:openapi | Emits the OpenAPI spec from the ChatApi definition via OpenApi.fromApi (no server needed). |
web/src/lib/api-types.ts | cd web && bun run gen:types | Regenerates openapi.json, then the typed API client from it with openapi-typescript. Re-run after any backend API change. |
web/src/routeTree.gen.ts | cd web && bun run gen:routes | TanStack Router's route tree (tsr generate). Normally produced automatically by the Vite plugin during dev/build; run this to generate it standalone (e.g. before typechecking). |
Prettier and ESLint are configured once at the repo root and cover both the
backend and the web/ frontend (single eslint.config.js + .prettierrc.json).
bun run format # write Prettier formatting
bun run format:check # verify formatting (used in CI)
bun run lint # ESLint (bun run lint:fix to autofix)
bun run typecheck # backend types; run the same in web/ for the frontend
scripts/loadtest/ has k6 scripts exercising the HTTP
CRUD endpoints and the /ws realtime fan-out under concurrent load — a
manual/on-demand tool for capacity checks, not a CI gate (issue #195). See
scripts/loadtest/README.md for setup
(including k6's separate install, since it isn't an npm/bun package) and
scenario details.
bun run loadtest:http # HTTP CRUD churn against posts/chats/messages
bun run loadtest:ws # /ws chat_updated fan-out latency
docker compose up (see above) for a local real
Postgres + Redis + backend stack.k8s/ has a Helm chart deploying the backend,
Postgres, and Redis to a cluster. The frontend deploys separately to
Cloudflare Workers instead — see k8s/README.md for both.The root package.json's version is the source of truth for releases (see
.github/workflows/tag-release.yml) and
must stay in sync with the Helm chart's version fields
(k8s/chat-platform/Chart.yaml's version/appVersion and
values.yaml's backend.image.tag) and with web/package.json's version.
After bumping the root package.json's version, run:
bun run sync:chart-version
and commit the result. CI's chart-version job re-runs this and fails the
build on drift.
.github/workflows/ci.yml runs on pushes to main
and on every pull request, with five parallel jobs:
format:check + lintopenapi.json/web/src/lib/api-types.ts and fails on driftbun test ./src, with a Redis service container for the one test that needs itThe Bun version is pinned in one place via the workflow's BUN_VERSION env var.