···11# final project csc 317
2233-- decentralized code competition platform on atproto
44-- stack uses vite + tanstack start + solidjs + tailwindcss
55-- deployed on cloudflare workers by CD pipeline
66-- database is a cloudflare d1 interacted via prisma
77-- the oauth-client-metadata.json is created by scripts/generate-metadata.ts
88-- this project uses `pnpm` for dependencies management
33+decentralized code competition platform on atproto
44+95- keep code well organized
1010-- use server function as much as possible
116- always use pnpm run scripts, not direct binary invocations
77+88+99+## commands
1010+1111+All commands run from `app/` via `pnpm run <name>` (workspace-wide: `pnpm
1212+--filter app …`).
1313+1414+- `dev` — Vite dev server on `127.0.0.1:5173`. Bound to `127.0.0.1`, not
1515+ `localhost`, because atproto OAuth (RFC 8252) rejects the `localhost`
1616+ hostname.
1717+- `build` / `preview` — production build / local preview of the built worker
1818+- `test` — `vitest run` (single file: `pnpm test path/to/file.test.ts`)
1919+- `check` — `tsc -p tsconfig.json`, no emit
2020+- `lint` / `lint:check` — eslint with/without `--fix`
2121+- `format` / `format:check` — prettier write/check
2222+- `db:generate` — regenerate Prisma client into `src/generated/prisma`
2323+- `wrangler:generate` — regenerate `worker-configuration.d.ts` from
2424+ `wrangler.toml` + `.env.example`
2525+- `lexicon:generate` — `lex-cli generate && lex-cli export` (types into
2626+ `src/generated/lexicons/`, schemas exported to `public/lexicons/`)
2727+- `postinstall` — runs all four generators in order. Re-run after editing
2828+ `prisma/schema.prisma`, `lexicons/**`, `wrangler.toml`, or `.env.example`.
2929+3030+3131+## architecture
3232+3333+- Single Cloudflare Worker entry: `@tanstack/solid-start/server-entry` (set in
3434+ `wrangler.toml`). Vite plugin order: Cloudflare → Tailwind → TanStack Start →
3535+ Solid (SSR on).
3636+- Routing is file-based under `src/routes/`. `src/routeTree.gen.ts` is generated
3737+ by `@tanstack/router-plugin` — never hand-edit. Root shell in
3838+ `src/routes/__root.tsx` wires `AuthProvider` → `ProfileProvider` → `Header` →
3939+ `<Outlet/>`.
4040+- Server functions are the primary RPC mechanism — defined with `createServerFn`
4141+ from `@tanstack/solid-start`. Server-only modules live in `src/server/` and
4242+ use the `.server.ts` suffix; they bind to `cloudflare:workers` env.
4343+- Persistence: Prisma client (`runtime = "workerd"`, sqlite provider) wrapped
4444+ with `@prisma/adapter-d1` against the `DB` D1 binding. Schema migrations are
4545+ **Wrangler D1 SQL files** in `migrations/` — not Prisma migrations. CI applies
4646+ them via `cloudflare/wrangler-action`.
4747+- Auth: atproto OAuth via `@atcute/oauth-node-client`. Client metadata is built
4848+ at runtime (`src/lib/oauth-metadata.ts`) and also baked into
4949+ `public/oauth-client-metadata.json` by `scripts/generate-metadata.ts`. JWKS
5050+ served at `/oauth/jwks`. In dev mode the client runs without a keyset;
5151+ production loads `PRIVATE_KEY_JWK` from env.
5252+- Lexicons: source TS specs under `lexicons/at.compiles.alpha/` (e.g. `problem`,
5353+ `submission`); generator emits typed clients into `src/generated/lexicons/`
5454+ and exports JSON to `public/lexicons/`.
5555+- Sessions: encrypted cookie via `useSession` from
5656+ `@tanstack/solid-start/server` (`src/lib/session.ts`), keyed by
5757+ `SESSION_SECRET`. Only stores an opaque token; user lookup goes through
5858+ `prisma.session`.
5959+6060+6161+## path aliases (tsconfig)
6262+6363+- `~/*` → `src/*`
6464+- `$/*` → `src/lib/*`
6565+- `@/*` → `src/lib/components/*`
6666+- `#/*` → `src/generated/lexicons/*`
6767+6868+6969+## generated — do not hand-edit
7070+7171+- `src/generated/prisma/`
7272+- `src/generated/lexicons/`
7373+- `src/routeTree.gen.ts`
7474+- `worker-configuration.d.ts`
7575+- `public/oauth-client-metadata.json`
7676+- `public/lexicons/`
7777+7878+7979+## deployment
8080+8181+GitHub Actions (`.github/workflows/frontend.yml`) gates on `check` +
8282+`lint:check` + `format:check` + `d1 migrations apply --local`. On `main`, it
8383+builds, applies migrations to remote D1, and deploys via `wrangler-action`.
8484+8585+Workspace is a single-package pnpm workspace (`app`);
8686+reproducible dev env via Nix flake (`nodejs_24`, corepack, `prisma-engines_7`).
128713881489<!-- intent-skills:start -->