dodil/erp-brick-business-partner

AGENTS.md

Instructions for agents working on brick-business-partner

This brick is built on erp-platform. Read its BRICKS.md before changing anything here — it holds the rules (ownership, use cases, data, identity, tests) and why each one exists.

Where a change goes

You are changing…It goes in
a rule about partners or their familysrc/brick_bp/domain/partner.py — and a test in tests/test_rules.py named for the story
who may do somethingsrc/brick_bp/application/use_cases.py — the permission on the declaration
a new action for people and agentsa new @BP.use_case in application/ — it becomes a route AND a tool
a column or tablesrc/brick_bp/schema.sql (append; never drop or rename) and infrastructure/tables.py

Never add an HTTP route or an MCP tool by hand. Never import SQLAlchemy, FastAPI or MCP in domain/.

Before you commit

pytest -q --tb=short        # rules + both doors, no bucket needed

Add a test to tests/test_doors.py for any new use case: the outcome through the API and through MCP, and the 404 for another person's row.

Don't

  • Don't write to another brick's tables — call its seam. And no other brick writes OURS: this brick being the only writer of the partner tables is the integrity mechanism (DataK3 does not enforce foreign keys).
  • Don't change bp_id_for: ids already stored in buckets depend on it — and hr derives a person's bp_id from person:<person_id> with it, without asking.
  • Don't let any write but sync_person reach a person partner, and don't return one to a caller without bp:person:read (404, never 403). Don't put a person's name or contact in bp_events.detail: field names only, so an erasure (BP-07) has nothing left to find.
  • Don't save a partner without its loaded version (PartnerRepository.save passes p.version as expected_version), and don't retry a change whose caller SENT a version — their 409 is the answer. A change with no version goes through _changing (re-run on a lost race).
  • Don't type an input as a bare int/str: BigId for a bp_id, the bounded strings for text (erp_platform.types) — the CRM audit's 500s were exactly those.
  • Don't let promote_partner give a role other than customer without bp:partner:write (H14).
  • Don't write an upsert or DELETE by hand — use the repository (DataK3's ON CONFLICT differs from Postgres).
  • Don't commit credentials or .env.