ai:prompt:review-pr-golang
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| ai:prompt:review-pr-golang [2026/06/11 14:00] – phong2018 | ai:prompt:review-pr-golang [2026/06/11 14:20] (current) – phong2018 | ||
|---|---|---|---|
| Line 11: | Line 11: | ||
| ## 1. Clean Architecture (Strict) | ## 1. Clean Architecture (Strict) | ||
| - | - Domain layer must have **zero** infrastructure dependencies | + | The project follows |
| - | - UseCase layer must **not** import `net/http`, gRPC, or any transport-specific package. | + | |
| - | - Dependencies | + | ``` |
| - | - All cross-boundary calls must go through | + | Presentation |
| - | - Flag any concrete struct | + | ↓ calls via TodoUsecase |
| + | Usecase | ||
| + | ↓ imports domain only | ||
| + | Domain | ||
| + | model/ | ||
| + | repository/ | ||
| + | | ||
| + | — FileStorage | ||
| + | ↑ implemented by | ||
| + | Infrastructure | ||
| + | repository/ | ||
| + | httpclient/ | ||
| + | s3/ — S3Client | ||
| + | ``` | ||
| + | |||
| + | ### Import matrix | ||
| + | |||
| + | | Layer | Allowed imports | Forbidden imports | | ||
| + | |-------|----------------|-------------------| | ||
| + | | `domain` | stdlib only | anything else | | ||
| + | | `usecase` | `domain` only | `infrastructure`, | ||
| + | | `infrastructure` | `domain`, `infrastructure/ | ||
| + | | `presentation` | `usecase` interfaces only | `infrastructure`, | ||
| + | |||
| + | Verify with: | ||
| + | ```bash | ||
| + | grep -r " | ||
| + | grep -r " | ||
| + | ``` | ||
| + | |||
| + | ### Interface placement rules | ||
| + | |||
| + | | Interface | Lives in | Reason | | ||
| + | |-----------|----------|--------| | ||
| + | | `TodoRepository` | `domain/ | ||
| + | | `NotificationClient` | `domain/ | ||
| + | | `FileStorage` | `domain/ | ||
| + | | `TodoUsecase` | `usecase/` | presentation consumes it — uses `usecase/ | ||
| + | | `Transaction` | `usecase/` | transaction boundary is application orchestration, | ||
| + | |||
| + | Flag `TodoUsecase` placed in `domain/` — it would force domain to import `usecase/dto`, breaking the stdlib-only rule. | ||
| + | |||
| + | ### DTO placement rules | ||
| + | |||
| + | | DTO type | Lives in | Tags | Used by | | ||
| + | |----------|----------|------|---------| | ||
| + | | Entity / Value Object | `domain/ | ||
| + | | Usecase DTO | `usecase/ | ||
| + | | Infrastructure DTO | `infrastructure/ | ||
| + | |||
| + | - [ ] No `json:` tags on domain entities — they must not be serialized directly to HTTP responses. | ||
| + | - [ ] No `db:` tags on usecase | ||
| + | - [ ] `infrastructure/ | ||
| + | - [ ] `usecase/ | ||
| + | |||
| + | ### Data flow at layer boundaries | ||
| + | |||
| + | ``` | ||
| + | HTTP JSON → bind/ | ||
| + | | ||
| + | → map (usecase impl) → domain/ | ||
| + | → TodoRepository.Create(ctx, | ||
| + | → map (usecase impl) → usecase/ | ||
| + | → JSON response | ||
| + | ``` | ||
| + | |||
| + | - [ ] Presentation must bind to `usecase/ | ||
| + | - [ ] Usecase impl is responsible for all mapping between `usecase/ | ||
| + | - [ ] Infrastructure impl is responsible for mapping `domain/ | ||
| + | |||
| + | ### Presentation layer rules | ||
| + | |||
| + | - [ ] `NewServer` must accept a `Dependencies` struct of usecase | ||
| + | - [ ] Handlers are thin: bind → validate → call usecase → return JSON. No business logic. | ||
| + | - [ ] Handlers must not import anything from `infrastructure/ | ||
| + | |||
| + | ### Transaction rules | ||
| + | |||
| + | - [ ] `WithinTransaction` is called | ||
| + | - [ ] Transaction boundary wraps writes | ||
| + | - [ ] Operations that must not roll back (e.g. sending | ||
| + | - [ ] Reads (`GetByID`, `List`) do not need a transaction. | ||
| + | |||
| + | ### Error handling rules | ||
| + | |||
| + | - [ ] Domain sentinel errors live in `domain/ | ||
| + | - [ ] Presentation middleware maps domain sentinels → HTTP codes via `errors.Is` / `errors.As` — this mapping lives only in middleware, never in usecase or infrastructure. | ||
| + | - [ ] `AppError.Err` (internal error) must never be serialized to the client response. | ||
| --- | --- | ||
| Line 47: | Line 134: | ||
| - [ ] Define interfaces in the **consumer package**, not in the implementor' | - [ ] Define interfaces in the **consumer package**, not in the implementor' | ||
| + | - **Exception for this project:** `TodoRepository`, | ||
| - [ ] Keep interfaces minimal — only the methods the consumer actually calls. | - [ ] Keep interfaces minimal — only the methods the consumer actually calls. | ||
| - [ ] Flag any interface with 5+ methods as a potential fat interface violation. | - [ ] Flag any interface with 5+ methods as a potential fat interface violation. | ||
ai/prompt/review-pr-golang.1781186451.txt.gz · Last modified: by phong2018
