98 lines
4.4 KiB
Markdown
98 lines
4.4 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Environment / Secrets
|
|
|
|
All project environment variables are stored in **Doppler**. When you need to access any secret or env var (e.g. API tokens, database URLs, credentials), fetch them via:
|
|
|
|
```bash
|
|
doppler run -- <command> # inject all secrets into a command
|
|
doppler secrets get SECRET_NAME # inspect a specific secret
|
|
```
|
|
|
|
Never use `.env` files. Do not ask the user to provide secrets manually — they are available via Doppler.
|
|
|
|
## Commands
|
|
|
|
### Docker (via `just` — the primary way to run services)
|
|
All services use Doppler for secrets injection. The `just` commands handle this automatically.
|
|
|
|
```bash
|
|
just up # Start all services in background
|
|
just up-fg # Start all services, stream logs
|
|
just down # Stop all services
|
|
just down-volumes # Full reset (destructive — removes all volumes)
|
|
just build # Rebuild all Docker images
|
|
just build-svc backend # Rebuild a specific service
|
|
just restart # Stop + rebuild + start
|
|
just logs # Tail all logs
|
|
just log backend # Tail a specific service
|
|
just shell backend # Open shell in running container
|
|
just init # One-shot init: MinIO buckets, PocketBase collections, Postgres
|
|
```
|
|
|
|
### Backend (Go)
|
|
```bash
|
|
cd backend
|
|
go vet ./...
|
|
go test -short -race -count=1 -timeout=60s ./...
|
|
go test -short -race -count=1 -run TestFoo ./internal/somepackage/
|
|
go build ./cmd/backend
|
|
go build ./cmd/runner
|
|
```
|
|
|
|
### Frontend (SvelteKit)
|
|
```bash
|
|
cd ui
|
|
npm run dev # Dev server at localhost:5173
|
|
npm run build # Production build
|
|
npm run check # svelte-check (type-check)
|
|
npm run paraglide # Regenerate i18n messages (run after editing messages/*.json)
|
|
```
|
|
|
|
## Architecture
|
|
|
|
Three services communicate via PocketBase records and a Redis/Valkey task queue:
|
|
|
|
**Backend** (`backend/cmd/backend`) — HTTP REST API. Handles reads, enqueues tasks to Redis via Asynq, returns presigned MinIO URLs. Minimal processing; delegates heavy work to the runner.
|
|
|
|
**Runner** (`backend/cmd/runner`) — Asynq task worker. Processes scraping, TTS audio generation, AI text/image generation. Reads/writes PocketBase and MinIO directly.
|
|
|
|
**UI** (`ui/`) — SvelteKit 2 + Svelte 5 SSR app. Consumes the backend API. Uses Paraglide JS for i18n (5 locales).
|
|
|
|
### Data layer
|
|
| Service | Role |
|
|
|---------|------|
|
|
| **PocketBase** (SQLite) | Auth, structured records (books, chapters, tasks, subscriptions) |
|
|
| **MinIO** (S3-compatible) | Object storage — chapter text, audio files, images |
|
|
| **Meilisearch** | Full-text search (runner indexes, backend reads) |
|
|
| **Redis/Valkey** | Asynq task queue + presigned URL cache |
|
|
|
|
### Key backend packages
|
|
- `internal/backend/` — HTTP handlers and server setup
|
|
- `internal/runner/` — Task processor implementations
|
|
- `internal/storage/` — Unified MinIO + PocketBase interface (all data access goes through here)
|
|
- `internal/orchestrator/` — Task orchestration across services
|
|
- `internal/taskqueue/` — Enqueue helpers (backend side)
|
|
- `internal/asynqqueue/` — Asynq queue setup (runner side)
|
|
- `internal/config/` — Environment variable loading (Doppler-injected at runtime, no .env files)
|
|
- `internal/presigncache/` — Redis cache for MinIO presigned URLs
|
|
|
|
### UI routing conventions (SvelteKit)
|
|
- `+page.svelte` / `+page.server.ts` — Page + server-side load
|
|
- `+layout.svelte` / `+layout.server.ts` — Layouts
|
|
- `routes/api/` — API routes (`+server.ts`)
|
|
- `lib/audio.svelte.ts` — Client-side audio playback store (Svelte 5 runes)
|
|
|
|
## Key Conventions
|
|
|
|
- **Svelte 5 runes only** — use `$state`, `$derived`, `$effect`; do not use Svelte 4 stores or reactive statements.
|
|
- **Modern Go idioms** — structured logging via `log/slog`, OpenTelemetry tracing throughout.
|
|
- **No direct MinIO/PocketBase client calls** outside the `internal/storage/` package.
|
|
- **Secrets via Doppler** — never use `.env` files. All secrets are injected by Doppler CLI.
|
|
- **CI/CD is Gitea Actions** (`.gitea/workflows/`), not GitHub Actions. Use `gitea.ref_name`/`gitea.sha` variables.
|
|
- **Git hooks** in `.githooks/` — enable with `just setup`.
|
|
- **i18n**: translation files live in `ui/messages/{en,es,fr,de,pt}.json`; run `npm run paraglide` after editing them.
|
|
- **Error tracking**: GlitchTip with per-service DSNs (backend id/2, runner id/3, UI id/1) stored in Doppler.
|