Files
libnovel/CLAUDE.md
Admin 2864c4a6c0
Some checks failed
Release / Test backend (push) Successful in 54s
Release / Check ui (push) Successful in 2m0s
Release / Docker (push) Failing after 2m20s
Release / Deploy to prod (push) Has been skipped
Release / Gitea Release (push) Has been skipped
chore: clean up release workflow and document Doppler usage
2026-04-15 20:14:45 +05:00

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.