Files
libnovel/CLAUDE.md
Admin 0f9977744a
All checks were successful
Release / Test backend (push) Successful in 1m1s
Release / Check ui (push) Successful in 2m12s
Release / Docker (push) Successful in 6m30s
Release / Gitea Release (push) Successful in 29s
feat: enforce bearer token auth on all /api/admin/* endpoints
Adds BACKEND_ADMIN_TOKEN env var (set in Doppler) as a required Bearer
token for every admin route. Also fixes PocketBase filter injection in
notification queries and wires BACKEND_ADMIN_TOKEN through docker-compose
to both backend and ui services. Includes CLAUDE.md for AI assistant guidance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 18:04:10 +05:00

3.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

Docker (via just — the primary way to run services)

All services use Doppler for secrets injection. The just commands handle this automatically.

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)

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)

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.