Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 95 additions & 25 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,106 @@
# AGENTS.md

> **Go Version**: 1.26+ (toolchain: go1.26.7)
> **Status**: Active — single source of truth for engineering decisions.
> AI coding-agent execution manual for snowgo.
>
> Go: 1.26+ (toolchain: go1.26.7).
>
> Goal: deliver the smallest necessary, verifiably correct change without compromising correctness, security, or maintainability.

## Document Index
## 1. Instruction Precedence and Document Roles

| Document | Scope |
|----------|-------|
| [CODING.md](./CODING.md) | Naming, error handling, logging, context, validation, concurrency |
| [ARCHITECTURE.md](./ARCHITECTURE.md) | Database design, transactions, caching, query optimization |
| [OPERATIONS.md](./OPERATIONS.md) | Security, testing, review checklist |
Resolve conflicts in this order:

1. The user's current explicit request, constraints, and explicitly confirmed exceptions.
2. The hard rules in this `AGENTS.md`.
3. The relevant project-specific references.
4. Existing conventions in the affected module, unless they conflict with a higher-priority rule.

The user's request defines the outcome and scope, but do not infer permission to bypass generated-file, data-integrity, security, or authorization constraints. Surface the conflict and obtain explicit confirmation before treating it as a policy exception.

`CODING.md` defines code-level practices; `ARCHITECTURE.md` defines layers, data, transactions, caching, and queries; `OPERATIONS.md` defines security, testing, configuration, release, and review practices.

Before implementation, read only the references relevant to the affected change surface. Use the Reference Index to decide what is required. Do not read unrelated references for a small localized change; if relevance or a boundary is unclear, read the applicable reference or ask.

Material ambiguity affecting APIs, data, permissions, security, compatibility, or scope must be surfaced with viable options. Do not silently select a high-risk interpretation.

---

## 2. AI Coding Behavior Guidelines

### Think Before Coding

For non-trivial changes, understand the requested outcome, identify material assumptions and ambiguities, consider affected boundaries and existing architecture, and define how the result will be verified. Ask when missing information would materially change the solution.

### Simplicity and Existing Patterns First

- Write only the minimum code needed for the current requirement. Do not add speculative features, abstractions, configuration, compatibility layers, or extension points.
- Before introducing a pattern for dependency injection, errors, logging, transactions, caching, API responses, authorization, or configuration, search for and reuse the established project pattern unless it is insufficient.
- Add a third-party dependency only when the standard library and existing dependencies are insufficient. Assess maintenance, license, security, and operational impact; then run `go mod tidy` and relevant tests.

### Surgical, Real Changes

- Inspect and preserve existing working-tree changes. Every changed line must be traceable to the task; do not opportunistically refactor, format, or clean up adjacent code.
- Do not silently ignore errors or turn unexpected errors into successful results. An explicitly best-effort operation must document its reason and log or measure failure.
- Do not claim a capability is complete when it is a TODO, placeholder, production stub, hard-coded success, or mock that does not perform the required behavior.

### Evidence-Based Execution

Define verifiable acceptance criteria. Prefer regression tests for bugs and cover important success, failure, authorization, and boundary paths for changed behavior. Report only verification actually performed, including skipped checks, reasons, and residual risk.

---

## 3. Standard Workflow

1. **Understand:** read the task, relevant code, and applicable references; identify the affected boundaries.
2. **Inspect:** check existing working-tree changes and define success criteria, risks, and relevant verification.
3. **Plan:** for non-trivial work, state concise steps with verification and material trade-offs.
4. **Implement:** follow existing patterns and the hard constraints below; keep the diff minimal.
5. **Verify:** run checks appropriate to the actual change scope and inspect the diff.
6. **Hand off:** report changed behavior, verification evidence, skipped checks, compatibility or release impact, and known risks.

---

## Core Rules

1. **Never** manually edit `internal/dal/model/` or `internal/dal/query/`.
2. Service owns transaction boundaries. DAO methods accept caller-provided `*query.Query` and never open transactions themselves. Multi-table mutations and audited business mutations that require operation logs use `WriteQuery().Transaction()`. Independent single-table writes may use a non-transactional `*query.Query` when atomic cross-table consistency is not required. Operation logs for audited business mutations are written synchronously within the same transaction through transaction-aware contracts or DAO methods.
3. All DAO methods that may participate in a transaction accept `*query.Query` as a parameter. The DAO does not care whether it runs in a transaction — the Service layer decides: pass `tx` inside `Transaction()`, pass `repo.Query()` or `repo.WriteQuery()` outside. There is only one method per DAO operation — no separate `Transaction*Xxx` variants.
4. Cache invalidation happens **after** DB commit, never inside a transaction.
5. Admin endpoints require `JWTAuth()` after login. Add `PermissionAuth(constant.PermXxx)` for privileged management or scoped business data endpoints. Login-only endpoints (current user permissions, server info, allowed dictionary lookups) must be documented in route comments. Middleware in `internal/router/middleware/auth.go`.
6. Service dependencies follow package boundaries: same-package services inject concrete `*XxxService`; cross-package service calls use stable contracts from `internal/service/admin/contract` when the dependency is shared infrastructure capability, and consumer-local interfaces only for narrow one-off domain dependencies. Do not call business Services inside an open transaction; only transaction-aware infrastructure contracts that receive the caller's `*query.Query` are allowed.
7. Use `xlogger.InfofCtx` / `xlogger.ErrorfCtx` for all logging.
8. Define sentinel errors in Service using `pkg/xerror/` codes; compare with `errors.Is`.
9. API layer validates all input before reaching Service.
10. No `panic()` in API/Service/DAO for business errors.
11. `created_at` mandatory for all tables; soft delete (`is_deleted tinyint(1) DEFAULT 0` + `deleted_at DATETIME(6) DEFAULT NULL`) is optional, decide per business need. Use for tables requiring audit/compliance/user undo (e.g., orders). Skip for high-volume logs and junction tables.
12. Run tests according to change scope before declaring complete: small, localized changes run affected package tests; broad/shared behavior changes run `go test ./...`. Always run `make lint`. Use coverage commands only when coverage is the explicit goal. Integration tests use `-tags=integration`; `make test-integration` covers pkg and Service integration tests and requires Redis/RabbitMQ plus `MYSQL_DSN` for Service tests.
13. Core and complex code must have comments. Update README / AGENTS docs alongside code changes.
## 4. Project Architecture Hard Constraints

- The primary business call direction is fixed: `Router → API → Service → DAO → DAL (GORM Gen) → MySQL`. Service may also use approved cache, queue, and external-service components. API never calls DAO directly; Service never calls GORM Gen query APIs directly.
- **Never manually edit** `internal/dal/model/` or `internal/dal/query/`. After a schema change, run `make gen do=add` or `make gen do=update` and inspect the generated diff. `make new-module domain=business module=order` produces a skeleton only.
- Service owns transaction boundaries. DAO receives the caller-provided `*query.Query` and never begins, commits, or rolls back transactions. Do not call business Services inside an open transaction.
- Use `WriteQuery().Transaction()` only for atomic multi-table writes, audited mutations, or other true transactional-consistency needs. Do not open a transaction solely because a read follows a write; use `repo.WriteQuery()` when primary-read consistency is sufficient to avoid replica lag.
- Audited mutations write operation logs synchronously in the same transaction. Service owns cache behavior; invalidate cache only after a successful database commit.
- API performs transport validation: binding, required fields, format, length, enums, and basic request limits. Service validates business rules and state-dependent preconditions.
- Admin endpoints after login require `JWTAuth()`; privileged or scoped endpoints require `PermissionAuth(constant.PermXxx)`. Every endpoint is public, login-only, or permission-protected. Explain only non-obvious public or login-only exceptions in code or route configuration.
- Same-package Services inject concrete Services. Cross-package shared infrastructure uses stable contracts in `internal/service/admin/contract`; narrow one-off dependencies use consumer-local interfaces. Contracts contain interfaces and DTOs only.
- Every table requires `created_at`; choose soft delete based on business need. Core or complex logic needs concise **Chinese** comments explaining **why**, not obvious code.

---

## AI Workflow
## 5. Mandatory Checks by Change Type

| Change surface | Required focus |
|----------------|----------------|
| Go code, errors, logging, context, validation, concurrency, dependencies | Read `CODING.md`; preserve established patterns and error semantics. |
| API or authorization | Read `CODING.md` and `OPERATIONS.md`; classify endpoint, validate transport input, preserve contract and error-code compatibility. |
| Schema, DAO, transactions, cache, queries | Read `ARCHITECTURE.md`; for schema changes also read `OPERATIONS.md`. Generate DAL code and assess indexes, migration artifacts, transaction scope, cache timing, and compatibility. |
| Writes, retries, queues, external calls | Read `ARCHITECTURE.md` and `OPERATIONS.md`; define idempotency, timeout, retry, durable side effects, and failure handling. |
| Security, configuration, release, observability | Read `OPERATIONS.md`; assess secrets, authorization, rollout, rollback, and production checks. |

---

## 6. Verification and Hand-Off Requirements

- Run affected-package tests for localized code changes; run `go test ./...` for shared or broad behavior changes. Run integration tests for affected critical paths when dependencies are available.
- For Go changes, format only changed files with `gofmt`, run scope-appropriate tests, and run `make lint`. If local lint tooling is unavailable, report the skipped check and do not claim lint passed; CI uses `golangci-lint v2.12.2` as the canonical gate. For documentation-only or non-Go changes, run relevant link, format, and diff checks.
- Do not change production behavior solely to satisfy a test when it conflicts with the requirement. Surface test/specification conflicts instead of optimizing blindly for green tests.
- Before hand-off, review `git diff` or equivalent and confirm every modified file and meaningful change belongs to the task and no unrelated user change was overwritten.

---

## 7. Reference Index

| Document | Read when |
|----------|-----------|
| [`CODING.md`](./CODING.md) | Changing Go code, errors, logging, context, validation, concurrency, or Service dependencies. |
| [`ARCHITECTURE.md`](./ARCHITECTURE.md) | Changing layers, database, DAO, transactions, caching, external calls, or query performance. |
| [`OPERATIONS.md`](./OPERATIONS.md) | Changing authorization, security, tests, configuration, release behavior, queues, or delivery review. |

Non-trivial changes: output plan before coding. Steps: understand task → identify files → plan → note risks → verify. For new database tables, run `make gen do=add` / `make gen do=update` to generate Model + Query before coding DAO/Service/API layers.
Update README or engineering references only when code behavior, configuration, APIs, or operational workflows actually change; avoid mechanical updates to unrelated documentation.
Loading
Loading