Development
Build, run and test Invarn locally.
Layout
| Folder | What |
|---|---|
server/ | The Go server: cmd/invarn, internal/ (bot, handlers, jobs → service → store and discord), db/ (migrations and queries), api/invarn.yaml |
web/ | The dashboard: React, Vite, shadcn/ui; the API client is generated by orval |
brand/ | Tokens, fonts and artwork, compiled into brand/dist by shasp |
site/ | The landing (Astro) and these docs (Fumadocs) |
Run it
Copy server/.env.example to server/.env and fill it in with a Discord application
of your own, with the redirect http://localhost:24102/auth/discord/callback. Then, in two
terminals:
cd server && docker compose -f compose.yaml -f compose.dev.yaml up --buildcd web && pnpm install && pnpm devThe server runs under Air, rebuilt and restarted on every save, and Vite reloads the dashboard. Open
localhost:24102/app/: Vite forwards /api and /auth to the server
(port 24100). Mail lands in Mailpit at localhost:24104.
The schema is edited in place until the first release, so after changing it, start from an empty
database: docker compose down -v.
Generated code
| Change | Then run |
|---|---|
server/db/queries/*.sql or the migration | sqlc generate (in server/) |
server/api/invarn.yaml | go generate ./internal/api/ and pnpm api (in web/) |
brand/tokens or brand/artwork | pnpm build (in brand/) |
Checks
cd server && go test ./... && golangci-lint runcd web && pnpm typecheck && pnpm lintThe linter keeps the layers apart: entry points never touch SQL, and services never touch HTTP, interaction types or Discord's REST client.