Ctrl K
ComunidadGuías…

AGENTS.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# OpenMeter

## Repository tooling

- Use the `Makefile` for common development tasks. The `justfile` is secondary.
- When tools are missing from the ambient shell, use:

  ```bash
  nix develop --impure .#ci -c <command>
  ```

- Always invoke `nix develop` from the repository root. Entering from a
  subdirectory writes CWD-relative devenv files and can break formatting or the
  pre-commit hook.
- Never run multiple `nix develop` commands concurrently in one worktree; they
  mutate shared `.devenv/` state.
- Dev shells share downloaded Go modules through `$HOME/go/pkg/mod`. `GOPATH`,
  `GOCACHE`, and installed tools remain per-worktree under `.devenv/state/go`.
  Existing worktree module caches are not migrated or removed automatically;
  clean them up separately after confirming no active shell uses them.
- `.nvmrc` is the GitHub Actions source of truth for Node. Keep it aligned with
  `node -v` in the Nix `.#ci` shell.
- For slow or noisy commands, save complete output to a temporary log outside the repository, preserve and report the exit status and log path, inspect bounded slices, and never rerun solely because displayed output was truncated.

## Repository invariants

- The repository has four Go modules: the production root, `collector`, the
  publishable `api/v3/client` SDK, and the test-only `e2e` module.
- Shared package imports can expand nested module dependency graphs. Run
  `make mod` and module-aware checks for affected consumers; root-module checks
  do not validate `collector` or `e2e` dependency metadata.
- The root module must never require `api/v3/client`. The nested SDK is not
  independently tagged, and local `replace` directives are invisible to
  downstream consumers.
- Root `go build ./...`, `go test ./...`, and `go vet ./...` exclude `e2e`.
  Use `make etoe` or `go test -C e2e ./...`; `make lint-go` and `make mod`
  already cover all three modules.

## Go conventions

- Name string enum constants `<Type><Value>`, for example
  `InvoiceStatusDraft`.
- Prefer methods when behavior is intrinsic to an existing domain type. Use
  freestanding functions when an operation has
  no natural receiver.
- Do not extract trivial or single-use helpers unless the name captures
  non-obvious domain intent. Inline pass-through wrappers.
- For non-trivial operations with multiple related parameters, define a named
  `<Operation>Input` struct that implements `models.Validator` through
  `Validate() error`. Put field and cross-field validation on the input and
  validate it at the owning boundary. Prefer this over a multi-argument
  operation paired with a separate `validate<Operation>(...)` helper. Do not
  introduce input structs for trivial single-value operations.
- For `Validate() error`, collect field errors and return
  `models.NewNillableGenericValidationError(errors.Join(errs...))`. Preserve
  field context with wrapped errors.
- Do not introduce `context.Background()` or `context.TODO()` to bypass context
  propagation. Propagate the caller context or remove an unnecessary context
  parameter.
- Never use `panic` in non-test code. Return and propagate errors.
- Map external provider failures to explicitly approved public HTTP messages;
  never return raw provider error text. Preserve the original cause for internal
  diagnostics.
- Production constructors must receive a `*slog.Logger`; do not fall back to
  `slog.Default()`.
- Prefer standard `slices` and `maps`, then `github.com/samber/lo` where it is
  clearer. Reuse `pkg/slicesx` and `pkg/syncx.OnceValues`; do not add local
  `ptr`, `must`, or equivalent wrappers.
- Mapping helpers between API, domain, and DB representations follow
  [Type Translation Naming](docs/development/type-conversions.md). Use
  `map`/`mapped`, not `project`/`projected`, for representation translation.
- `alpacadecimal.Decimal.Div` can round: its fallback uses `DivRound` at
  `DivisionPrecision` (16 decimal places by default), with ties away from zero.
  Do not use `Div` before exact floor/ceiling, remainder comparisons, or boundary
  decisions. For example, dividing decimal `9.99999999999999999` by `10` rounds
  to `1` while the exact remainder is non-zero. Use `QuoRem(divisor, precision)`
  for a truncating quotient and exact remainder, accounting for signs when
  applying floor or ceiling. Apply the intended rounding once at the owning
  precision; increasing global division precision only moves the boundary and
  is not a fix.

## Testing conventions

- PostgreSQL-backed tests require PostgreSQL and
  `POSTGRES_HOST=127.0.0.1`; otherwise many suites silently skip.
- Root-package tests using `confluent-kafka-go` require `-tags=dynamic`. The
  standalone `e2e` module does not.
- Keep domain test helpers under `openmeter/.../testutils` independent from
  `app/common`; construct repositories, adapters, services, and locks from
  their package constructors.
- Prefer production-backed/service-backed fixtures when the real path can
  express the scenario. Hardcode suite-wide behavior into the shared harness
  instead of exposing per-test knobs.
- Use `t.Context()` when a `testing.T` or `testing.TB` is available.
- Add a test helper only when reused or when its name captures non-obvious
  domain semantics. Inline one-use setup/assertion wrappers and remove dead
  helpers.
- Begin non-trivial service/lifecycle subtests with concise `given`, `when`,
  and `then` intent comments.
- Pair `clock.FreezeTime(...)` immediately with `defer clock.UnFreeze()` in the
  same scope.
- When precision permits, compare `alpacadecimal.Decimal` through
  `InexactFloat64()` with `require.Equal`; inline one-off expected balances.

See [Testing](docs/development/testing.md) for harness patterns and examples.

## Documentation conventions

- Comments and docstrings explain intent, domain constraints, lifecycle state,
  and failure consequences that are not obvious from the code. Do not narrate
  conditions the reader can already see.
- Document domain helpers whose names compress important business semantics;
  describe observable behavior and why excluded cases are excluded.
- Preserve explanatory comments during refactors unless the change makes them
  false or misleading.
- Keep project documentation short enough that humans will read it.
- Write comments like you're explaining the code to a teammate: plain words,
  concrete reasons, no formal filler. Keep the useful explanation:

  Bad:
  ```go
  // scopedEntries applies the account, route, provenance, and whole-history
  // exclusions shared by both branches. AsOf is left to each branch: filtering
  // here would hide future postings whose balance impact must be preserved.
  ```

  Good:
  ```go
  // Apply the shared filters, but keep entries after AsOf: we need those to see
  // how low the balance gets later.
  ```

## Further guidance

- TypeSpec and SDK generator work follows [api/spec/AGENTS.md](api/spec/AGENTS.md).
- Focused developer guides cover [service packages](docs/development/service-patterns.md),
  [testing](docs/development/testing.md),
  [refactoring](docs/development/refactoring.md),
  [type conversions](docs/development/type-conversions.md), and
  [collection helpers](docs/development/collection-helpers.md).

For changes or reviews that affect domain behavior, use the
[`domain-docs`](.agents/skills/domain-docs/SKILL.md) skill after establishing
the scope to locate the relevant package documentation. Treat domain docs as
intended semantics and code and tests as current behavior; investigate
discrepancies instead of automatically preferring either.

## CodeGraph and complex work

- Use CodeGraph when it materially shortens symbol, caller, flow, or impact
  exploration. If the worktree is not initialized, run
  `nix develop --impure .#ci -c codegraph init -i` from the repository root,
  then retry. Check `codegraph status`; if initialization left a truncated
  index, rebuild it with `nix develop --impure .#ci -c codegraph index` before
  falling back. Its server keeps a healthy index synchronized; do not manually
  sync it.
- Treat graph relationships as navigation hints. Current source and tests are
  authoritative; fall back to normal source navigation only when initialization
  fails, CodeGraph is unavailable, or its results are inconclusive.
- When planning or implementing ambiguous, design-heavy, or cross-cutting
  engineering changes, use the
  [`iterative-engineering-design`](.agents/skills/iterative-engineering-design/SKILL.md)
  skill.

## Maintaining agent guidance

- Keep automatically required repo guidance in this file. Use skills for
  task-shaped procedures and explicitly linked docs for scoped detail; do not
  assume root-started agents will discover descendant `AGENTS.md` files.
- Fold new guidance into the relevant section and merge or remove duplicates.
- `.agents/skills` is the source of truth for skills; `.claude/skills` contains
  compatibility symlinks. Keep skill text usable by both Codex and Claude.