Files
book-comic-library/AGENTS.md
T
XingfenD 2fccf3f2b3
CI / backend (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
docs: record TS side-by-side + legacy-peer-deps conventions (AGENTS.md + .npmrc)
2026-09-16 11:43:21 +08:00

4.0 KiB

AGENTS.md

Safety Rules

  • Dev branch naming: {feat|fix|docs|chore}/{branch-name} (e.g. feat/file-tag-done, fix/tree-render).
  • Before git commit: run git branch --show-current. If on master, do NOT commit — ask user for a branch name (suggest one based on the changes), create it, commit there.
  • Every user-visible change gets a changelog entry: WebUI changes (files under frontend/) → docs/CHANGELOG_web.md, everything else → docs/CHANGELOG.md; never duplicate an entry across both. Higher versions on top.
  • CHANGELOG entry format: same entry has English line then Chinese line on consecutive lines (no blank line between them); different entries are separated by a blank line.
  • docs/README.md and docs/README_zh.md stay content-equivalent; update them in the same change.

Docker deployment (dev & release)

  • dev = deploy/docker-compose.dev.yml: source bind-mounted (../backend:/app, ../frontend:/app with an anonymous volume on /app/node_modules), target: dev images; api runs go mod download && dlv debug ./cmd/webui (delve on 2345), web runs npm run dev (hot reload, no rebuild needed); infra ports exposed to host (postgres 5432, redis 6379); startup gated on healthchecks.
  • release = deploy/docker-compose.yml: multi-stage *.prod Dockerfiles (target: runner) with compiled binaries, no source mounts; infra ports stay on the internal network only.
  • Persisted state lives only in named volumes booklib_{postgres,redis}_data — same names in both files, so dev and release see the same data. Only down -v wipes them.
  • Books on disk: host deploy/api/storage is mounted as /data/books (BOOKS_DIR); uploads land there and the scanner picks them up.
  • Rendered configs deploy/nginx/nginx.conf, deploy/nginx/conf.d/default.conf, deploy/redis/redis.conf (mounted :ro) come from their *.tpl via deploy/prepare.sh — edit the template, rerun prepare.sh, restart; stale files in a container mean you forgot to rerun. Host logs under deploy/logs/.
  • Tear down with down, not rm, or the web image's anonymous node_modules volume gets orphaned.

Project structure

Root: docs (docs + changelogs), backend (Go webui service), frontend (node app, served via nginx in release), deploy (compose stacks, rendered configs, host logs). Actual layout is visible via ls; only rules not derivable from it are listed here.

backend

  • cmd/: each subdir is exactly one main package; main.go only bootstraps (load config, wire deps, serve, graceful shutdown) — no business logic, and nothing outside cmd imports cmd.
  • cmd/webui/api is the single source of truth for the endpoint contract; the frontend aligns with it.
  • Handlers stay thin (bind/validate, call internal, map errors) — never touch the DB or implement domain rules; SQL and business rules live behind internal boundaries.
  • Business code defaults to internal/; pkg/ is opt-in public surface shared with other repos — keep it small, never leak internal types through it.

frontend

  • Talks to the backend only over the HTTP APIs in backend/cmd/webui/api — no direct infra access (DB, redis) from the browser app.
  • Build output (dist/) is disposable and git-ignored; only src/public are committed.
  • Dev runs from the source mount with node_modules provided by the image — install new deps inside the container and commit the lockfile.
  • TypeScript runs side-by-side (frontend/package.json): typescript = TS 6.0.2 JS API for tooling (typescript-eslint doesn't support TS 7 yet), @typescript/native = native 7.0.2 providing tsc. Do not re-alias typescript to 7.x until typescript-eslint ships TS 7 support. Plain npm install needs --legacy-peer-deps (also pinned in frontend/.npmrc); npm ci is unaffected.

deploy

  • Only config templates/examples are tracked by git; rendered *.conf and logs/ are git-ignored.
  • Service-specific host dirs (storage, config) go under deploy/{$service_name}/, never loose at the repo root.