# 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 same-category aggregates only. Exclude the active merchant and suppress the benchmark unless at least 10 other merchants and 1,000 combined peer sessions contribute in the selected period. Use one value per peer merchant to calculate the cohort median and direction-aware performance percentile; never transaction-weight by default. - 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 Argon2id with reviewed parameters and a unique salt. Sessions are server-side and revocable; browsers receive only an opaque token in a `Secure`, `HttpOnly`, `SameSite=Lax` cookie. Never put authentication tokens in browser storage. - 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.