Instructions for agents working on brick-pipeline
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 deals, stages or the forecast | src/brick_pipeline/domain/pipeline.py — and a test in tests/test_rules.py named for the story |
| who may do something, or which rows they see | src/brick_pipeline/application/use_cases.py — the permission, or _sees() / _load(write=True) |
| a new action for people and agents | a new @PIPE.use_case in application/ — it becomes a route AND a tool |
| a column or table | src/brick_pipeline/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 (QUOTES, PARTNERS in use_cases.py).
- Don't put
source_refback on a person's route or tool, and don't givepipeline:opportunity:link_sourceto a person role: whoever can name a source can plant the deal a conversion lands on (C2). - Don't count an accepted quote as a win's evidence without its customer and currency matching the deal's, or
one a reopen voided (C1, H3). Don't let a closed deal move except through
reopen_opportunity. - Don't save a deal without its loaded version, and don't retry a change whose caller sent one.
- Don't store a derived figure (weighted value, forecast, at-risk): compute it on read.
- 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.