35 lines
3.6 KiB
Markdown
35 lines
3.6 KiB
Markdown
# 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.
|
|
|
|
### 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.
|