133 lines
6.9 KiB
Markdown
133 lines
6.9 KiB
Markdown
# Backend Agent Guidelines
|
|
|
|
These instructions extend the repository-wide rules in the root `AGENTS.md`
|
|
and apply whenever a task adds or modifies backend code, including Go and
|
|
protobuf files under `backend/`.
|
|
|
|
Before completing the task, review the entire backend diff produced by the
|
|
current task, fix every in-scope issue found, and then perform the required
|
|
validation. Use the
|
|
[`$review-backend-change`](../.agents/skills/review-backend-change/SKILL.md)
|
|
skill to perform this completion workflow.
|
|
|
|
## Reuse existing definitions
|
|
|
|
- Search the repository before introducing a protobuf message, enum, Go struct,
|
|
interface, or shared domain type.
|
|
- Reuse or extend the canonical existing definition when its semantics match.
|
|
Do not create parallel representations or conversion layers for the same
|
|
concept without a clear architectural reason.
|
|
- Avoid naming stutter in packages, types, fields, parameters, and access paths.
|
|
Each nested name should add meaning instead of repeating its parent context.
|
|
For example, prefer a concise path such as `payment.Details.ID` over
|
|
`payment.Payment.PaymentID`.
|
|
|
|
## Reuse shared database and messaging infrastructure
|
|
|
|
- All database integrations must use the existing shared database wrappers in
|
|
`backend/shared/database`. Do not bypass them with direct database clients or
|
|
create feature-local replacements.
|
|
- All NATS connections must use shared messaging drivers owned by the
|
|
`backend/shared` library module. Keep reusable NATS drivers in
|
|
`backend/shared/messaging`; executable modules must consume that package.
|
|
Do not open direct NATS connections or implement separate connection
|
|
management in a feature or service.
|
|
- If the shared messaging package is missing, consolidate the existing driver
|
|
into `backend/shared/messaging` and reuse it. Do not create another
|
|
feature-local driver or import a sibling executable module's infrastructure.
|
|
- Search for the existing wrappers, drivers, and their usage before implementing
|
|
an integration. Reuse their connection lifecycle, configuration, retries, and
|
|
other infrastructure behavior instead of copying or rewriting it.
|
|
- If an integration needs a capability the shared infrastructure does not yet
|
|
expose, extend the canonical wrapper or driver. Keep reusable infrastructure
|
|
there and domain-specific behavior in the owning module.
|
|
- During review, check that database and NATS integrations use these shared
|
|
paths and remove any duplicated infrastructure introduced by the task.
|
|
|
|
## Use the project error model
|
|
|
|
- Do not introduce `fmt.Errorf` or `errors.New`. Use the constructors and
|
|
wrapping helpers in `backend/shared/errors`.
|
|
- Preserve the underlying cause when adding context by using an appropriate
|
|
`merrors` wrapping helper.
|
|
- When no suitable project error exists, add the smallest generally useful
|
|
definition or helper to `backend/shared/errors` instead of creating an ad hoc error
|
|
elsewhere.
|
|
|
|
## Keep modules cohesive and names concise
|
|
|
|
- Review touched files for excessive size, mixed responsibilities, duplicated
|
|
logic, and poor separation of concerns.
|
|
- Refactor oversized contributions into focused, cohesive files or packages.
|
|
Do not split code mechanically; organize it along clear domain or
|
|
architectural boundaries.
|
|
- Avoid repeating directory or package context in child directory and file
|
|
names. For example, prefer `payment/widget.dart` over
|
|
`payment/payment_widget.dart`.
|
|
|
|
## Review implementation quality
|
|
|
|
- Review the current task's backend contribution for correctness, readability,
|
|
maintainability, testability, and consistency with the surrounding
|
|
architecture.
|
|
- Keep public APIs and module boundaries small and intentional. Remove
|
|
unnecessary indirection, duplication, dead code, and speculative abstractions.
|
|
- Add or update tests for changed behavior, edge cases, and failure paths.
|
|
- Fix all findings caused by the current task before reporting completion.
|
|
|
|
## Review logging
|
|
|
|
- Ensure the contribution has sufficient structured logging at meaningful
|
|
operational and domain boundaries. Include useful identifiers and context,
|
|
but never log credentials, secrets, or sensitive payment data.
|
|
- Follow the repository's logging style and use levels consistently:
|
|
- `Debug`: fine-grained runtime execution tracking useful during debugging.
|
|
- `Info`: important payment-domain events, module-boundary operations,
|
|
effective module configuration, and noteworthy but expected deviations from
|
|
the usual path.
|
|
- `Warn`: runtime errors and unexpected conditions from which the service can
|
|
continue or which are returned to a caller.
|
|
- `Error`: unrecoverable failures that cause, or imminently lead to, service
|
|
or component termination.
|
|
- Avoid logging the same error repeatedly at multiple layers. Log it where the
|
|
layer has enough context to make the event actionable.
|
|
|
|
## Required validation
|
|
|
|
- From the repository root, run `make test` and `make lint-backend`, plus every
|
|
applicable command from the root `AGENTS.md` change-scoped security
|
|
requirements, after all review fixes are complete.
|
|
- All commands must succeed before the task is reported as complete. Fix
|
|
failures introduced by the current task; do not silently skip, suppress, or
|
|
weaken checks.
|
|
- Report the commands run and their outcomes in the final response. If an
|
|
external or environmental blocker prevents a command from running, report
|
|
the exact command, failure, and blocker explicitly; do not claim successful
|
|
validation.
|
|
|
|
## SXCHNGE provider boundary
|
|
|
|
SXCHNGE owns auth, sessions and customer management. SXCHNGE is one organization
|
|
inside Sendico. This organization reference belongs only in the public provider
|
|
adapter configuration. Local customers have no organizations, tenant IDs,
|
|
membership, roles or policy engine. Do not copy platform scaffolding to satisfy
|
|
unused dependencies; remove those dependencies from the selected components.
|
|
Copied BFF components are locally owned and may diverge.
|
|
Use only Sendico's public HTTP API for platform operations. Never import sibling
|
|
Sendico modules or access its database, internal gRPC APIs, discovery or message
|
|
bus. Keep consumed public wire contracts inside the owning adapter, separate
|
|
from local DTOs and models. Do not copy unused API snapshots.
|
|
Resolve the configured provider organization and customer resource ownership on
|
|
the server. Never treat all customers as the backend integration principal.
|
|
Use the copied structured logger, injected at operational boundaries.
|
|
|
|
## Go module structure
|
|
|
|
`backend/` groups independent Go modules; it is not itself a Go module.
|
|
`product/` is the customer-facing executable and owns its `main.go` and `go.mod`.
|
|
`shared/` is a library module for reusable infrastructure and has no entry point.
|
|
Backoffice belongs in its own executable module (`backoffice/`) when implemented,
|
|
with its own entry point and configuration, not inside the product executable.
|
|
Keep feature models, storage, services and transport together inside their owning
|
|
module. Shared infrastructure must not import a product or backoffice module.
|