update llm.txt

This commit is contained in:
2025-12-22 18:56:44 +08:00
parent 0d63ecc9c2
commit d04e2ee693

View File

@@ -10,6 +10,7 @@ This file condenses `backend/docs/dev/http_api.md` + `backend/docs/dev/model.md`
- MUST: HTTP module folder name MUST be `snake_case` (e.g. `tenant_public`), not `camelCase`/`mixedCase`.
- DO keep controller methods thin: parse/bind → call `services.*` → return result/error.
- DO regenerate code after changes (routes/docs/models).
- MUST: in `backend/app/services`, prefer the generated GORM-Gen DAO (`backend/database/models/*`) for DB access; treat raw `*gorm.DB` usage as a last resort.
- MUST: after adding/removing/renaming any files under `backend/app/services/`, run `atomctl gen service --path ./app/services` to regenerate `backend/app/services/services.gen.go`; DO NOT edit `services.gen.go` manually.
- MUST: a single service's methods MUST live in a single file; do NOT split one service across multiple files (e.g. `type user struct{}` in `user.go` but methods in `user_admin.go`), because `atomctl gen service` uses filenames to infer services and will generate incorrect `services.gen.go`.
- DO add `// @provider` above every controller/service `struct` declaration.
@@ -155,6 +156,42 @@ Models live in:
- `atomctl gen model`
---
## 3) Service-layer DB access (GORM Gen)
This project uses a PostgreSQL-focused GORM-Gen variant (`go.ipao.vip/gen` + generated `backend/database/models/*`).
Reference: `backend/llm.gorm_gen.txt`.
### 3.1 Query style (preferred)
- MUST: in services, build queries via:
- `tbl, q := models.<Table>Query.QueryContext(ctx)`
- Use type-safe conditions (`tbl.ID.Eq(...)`, `tbl.TenantID.Eq(...)`, `tbl.DeletedAt.IsNull()`, etc).
- DO NOT: use string SQL in `Where("...")` unless absolutely necessary.
### 3.2 Transactions
- MUST: use Gen transaction wrapper so all queries share the same tx connection:
- `models.Q.Transaction(func(tx *models.Query) error { ... })`
- Inside tx, use `tx.<Table>.QueryContext(ctx)` / `tx.<Table>.WithContext(ctx)`
- DO NOT: use `_db.WithContext(ctx).Transaction(...)` in services unless Gen cannot express a required operation.
### 3.3 Updates
- Prefer `UpdateSimple(...)` with typed assign expressions when possible.
- Otherwise use `Updates(map[string]any{...})`, but MUST:
- include tenant boundary conditions (`tenant_id`) in the WHERE,
- avoid updating columns by concatenating user input.
### 3.4 Columns not in generated models (temporary escape hatch)
If migrations add columns but `atomctl gen model` has not been re-run yet, the typed `models.<Struct>` will not contain those fields.
In this case:
- Use `q.UnderlyingDB()` (from Gen DO) to do a narrow query/update (single table, explicit columns).
- Add a short Chinese comment explaining why, and that `atomctl gen model` should be run when DB is reachable.
- Avoid spreading this pattern: keep it localized to one function.
### 2.2 Enum strategy
- DO NOT use native DB ENUM.