docs: changelog + README backend structure for batch C (Task 29)
- CHANGELOG [Unreleased]: consolidated the duplicated Added/Changed/Fixed groups left by earlier batches into one group each (no entry dropped); added batch C entries — port-based restructure, media/upload domain packages, sweep moved to scanner ticker (B16), router contract test, portsfake unit-test layer. Upload-sweep wording no longer promises the old 24h opportunistic request-path behaviour. - README.md / README_zh.md: new 'Backend structure' section documenting the port/fake layout (cmd/webui composition root, handlers as HTTP-only, internal/ports + portsfake, media/upload/store/scanner/bookfile responsibilities) and the two-tier testing approach (real PG+Redis integration vs fake-injected unit, route table pinned by contract test) Gate: gofmt clean, go vet clean, go test -p 1 all pass (0 skip), scripts/smoke.sh ALL SMOKE TESTS PASSED against a live webui on :18080
This commit is contained in:
@@ -78,6 +78,22 @@ Schema changes go through the ordered migration system in `backend/internal/db/m
|
||||
|
||||
Local gate before each batch merge: `go vet ./... && gofmt -l . && go test -p 1 -count=1 ./...` with dev PG+Redis running.
|
||||
|
||||
## Backend structure
|
||||
|
||||
The backend is organized around consumer-side port interfaces (hexagonal style):
|
||||
|
||||
- `cmd/webui` — binary entry point and composition root: `main.go` builds concrete implementations (`store.Store`, `redispkg.R`, `scanner.Scanner`, `media.M`, `upload.U`) and hands them to `api.NewRouter`, which only accepts the port interfaces.
|
||||
- `cmd/webui/handlers` — HTTP layer: request binding, auth/authz, error → status mapping. No SQL, no archive/file logic.
|
||||
- `internal/ports` — the small interfaces handlers depend on (`UserStore`, `LibraryStore`, `BookStore`, `ProgressStore`, `BookmarkStore`, `RateLimiter`, `Scanner`, `Media`, `UploadSessions`) plus shared sentinel errors. Interfaces live on the consumer side, implementations satisfy them.
|
||||
- `internal/ports/portsfake` — hand-written in-memory fakes for every port, with error semantics mirroring the real store (`pgx.ErrNoRows`, `ErrLastAdmin`, PgError 23505). Handler unit tests run against these with no PG/Redis.
|
||||
- `internal/media` — cover/page extraction, page-index cache (Redis-backed), atomic cache writes.
|
||||
- `internal/upload` — chunked upload session lifecycle (init/part/status/complete/sweep).
|
||||
- `internal/store` — all SQL, one place.
|
||||
- `internal/scanner` — library walk, ingest (add/update/delete in one pass), sweep riding the scan ticker.
|
||||
- `internal/bookfile` — shared file utilities (`SafeName`, `Contains`, `Hash`, `FormatFromExt`, cache dir layout).
|
||||
|
||||
Testing is two-tiered: integration tests hit a real PG+Redis via the full router (`handlers/*_test.go` with `setupAPI`), unit tests hit the same router with `portsfake` injected (`handlers/*_unit_test.go`). The route table itself is pinned by `TestRouterContract` in `cmd/webui/api`.
|
||||
|
||||
## CI
|
||||
|
||||
- Workflow: `.github/workflows/ci.yml` (standard GitHub Actions syntax, Gitea Actions compatible).
|
||||
|
||||
Reference in New Issue
Block a user