3.3 KiB
Repository Guidelines
Project Structure
src/ holds the React client: components in src/components/, hooks in src/hooks/, lesson data in src/data/, and CSS in src/styles/. server.ts is the Bun entrypoint; server-only code lives in server/ (auth.ts, db.ts, config.ts). Nix files are split between flake.nix, generated bun.nix, and reusable deployment pieces in nix/.
Local Development
bun install: install dependencies frombun.lock.bun run dev: start the Bun server with HMR on port5174.bun run lint: run ESLint.bun run typecheck: runtsc -b.bun run build: bundle the Bun server intobuild/.bun run update:bun-nix: regeneratebun.nixafter dependency changes.
Run bun run lint && bun run typecheck && bun run build before opening a PR.
Coding Conventions
TypeScript is strict on both client and server. Follow the existing style: single quotes in frontend files, PascalCase component filenames, useX hook names, and lowercase data/config modules. Keep runtime configuration in server/config.ts rather than scattering process.env reads.
Bun2nix Setup
This repo uses Bun as the package manager and bun2nix for reproducible Nix builds. The flow is:
bun.lockis the source of truth for JS dependencies.bun.nixis generated frombun.lockwithbun run update:bun-nix.flake.niximports thebun2nixoverlay and exposespackages.<system>.defaultplusnixosModules.default.nix/package.nixusesbun2nix.fetchBunDepswithbun.nix, runsbun run build, and installs the bundledserver.jsplus frontend assets as theleo-edexecutable.
Whenever dependencies change, update both bun.lock and bun.nix in the same commit. CI checks that bun.nix matches the lockfile by regenerating it and failing on diff.
Server and Deployment Model
This repo is the application source, not the full server configuration. Production is intended to be managed from a separate NixOS infra repo that imports this flake and sets services.leo-ed.package = inputs.leo-ed.packages.${pkgs.system}.default;. The included module in nix/module.nix defines the systemd service, runtime env (APP_ORIGIN, PORT, SQLITE_PATH, SESSION_COOKIE_SECURE), and persistent state directory.
server/config.ts exists so production behavior is explicit: WebAuthn origin/RP ID, SQLite path, bind host, and secure cookies should come from NixOS service configuration, not reverse-proxy accident.
Forgejo and Woodpecker
Forgejo should be the canonical remote and PR system. Woodpecker runs repo CI from .woodpecker.yml: install deps in the flake dev shell, lint, typecheck, build, regenerate bun.nix, and nix build .#default. That validates the app package only.
Production deployment belongs in the separate infra repo. The expected flow is:
- merge app changes in Forgejo
- update the infra repo input that pins this app revision
- let Woodpecker in the infra repo run
nixos-rebuild --target-host ...
Keep app CI and host deployment separate; this repo proves the package is buildable, while the infra repo owns the actual VPS switch.
PR Guidance
Use focused, imperative commit messages such as auth: honor configured app origin or nix: package app with bun2nix. PRs should list verification steps and mention any dependency updates, bun.nix regeneration, or NixOS module changes.