Files
zarinpal-analytics-backend/AGENTS.md

46 lines
4.7 KiB
Markdown

# Backend Agent Operating Contract
## Phase gate
This repository is in specification mode. Do not create `go.mod`, application packages, migrations, containers, or executable code until the relevant capability spec is approved.
For every Go-related task, always invoke and follow the `golang-how-to` skill, then the secondary Go skills it routes to. Before creating the Go project layout, ask the user to approve the architecture style and dependency-injection approach in that order.
## Product invariants
- Use the canonical domain terms in `CONTEXT.md`; update that glossary when a term's meaning is approved, without adding implementation details to it.
- The backend is the authority for authentication, authorization, tenant isolation, metric definitions, and data provenance.
- Every merchant-scoped query derives merchant identity from the authenticated server-side session; never trust a client-supplied merchant identifier as authorization.
- Cross-merchant results are anonymized aggregates only. Exclude the active merchant and suppress the benchmark unless at least 10 other merchants and 1,000 combined peer sessions contribute to the approved cohort/window.
- Treat `payer_card_key` as an opaque, merchant-scoped source token with unverified upstream semantics. Retain it unchanged only for internal deterministic analytics; never expose it through merchant APIs, logs, exports, or AI inputs, and never describe it as a card number or verified person identifier.
- Use integer minor currency units or an explicitly documented fixed-precision representation; never floating point for money.
- Interpret timezone-naive challenge timestamps as `Asia/Tehran`, preserve their source provenance, and normalize canonical database/API timestamps to UTC `timestamptz`/ISO 8601. Any change to this assumption requires a new import version and ADR.
- Raw imports are immutable inputs; corrections are new import versions, not silent mutation.
- CSV ingestion is a one-time bootstrap/recovery command only. Never add a file watcher, polling schedule, recurring CSV ETL, or ownership of ZarinPal's production writes without a new approved spec.
- Treat source `adjusted_fee` as the merchant's real fee for this product. Normalize it once per session as `fee_amount_rial`; do not sum the repeated attempt-row value.
- Treat both `Paid` and `Verified` as successful bank payments. `Paid` still requires merchant verification; `Verified` is finalized. Never classify `Paid` as failure.
## Go baseline after approval
- Keep `main` packages thin under `cmd/`; business code lives under `internal/`.
- Wire dependencies manually with explicit constructors at the composition root. Do not introduce a DI container or code generator unless a later ADR documents measured wiring/lifecycle complexity.
- Use explicit constructors; avoid `init()` side effects and mutable globals.
- Configuration comes from validated environment variables. Logs go to stdout as structured records without credentials, card keys, or sensitive payloads.
- Propagate `context.Context`; bound external calls, queues, batches, and database pools.
- Use parameterized queries and transactions with explicit boundaries. Stream/bulk-load the multi-million-row input instead of holding it in memory.
- Use Ent for application persistence and relationship modeling. Use pgx with PostgreSQL `COPY` for the bulk-import staging path; do not force high-volume ingestion through row-by-row ORM operations.
- Database migrations are explicit, versioned, reviewed artifacts applied by a dedicated migration/deployment step. Never run Ent automatic schema creation against production during application startup.
- Passwords use an approved adaptive hash (Argon2id or bcrypt per the approved auth spec); sessions use secure, HttpOnly cookies and server-side revocation.
- Required verification includes unit/integration tests, race detection where applicable, `go vet`, `golangci-lint`, `govulncheck`, and migration/import tests.
## Git and documentation
- Use atomic Conventional/Commitizen commits.
- Track specs, ERD/schema definitions, migrations, importer code, validation rules, manifests/templates, and runbooks.
- Ignore raw CSV archives, database volumes/dumps, credentials, and generated runtime data.
- Changes to a metric, API, schema, authorization rule, or AI data boundary require the corresponding spec/ADR update.
## AI boundary (post-MVP)
AvalAI is accessed only from the backend using a server-held API key. Prefer the simplest bounded LLM call/workflow that satisfies the approved use case. Send minimized, sanitized aggregates with explicit budgets/timeouts; persist trace metadata and deterministic inputs, not unnecessary sensitive prompts. AI output is advisory and must cite underlying deterministic metrics.