---
name: 'BUSINESS-RULES: Document'
description: Retroactively document business rules implicit in existing code for a given aggregate.
category: Business Rules
tags: [business-rules, catalog, retroactive, bootstrap]
---

Retroactively document business rules implicit in code for a given aggregate.

Use this when:
- Bootstrapping the catalog for a bounded context that doesn't have rules yet.
- A bug exposes a rule that was never written down.
- You have an external document (e.g., a Word file converted to markdown) that contains rules and want to map them to the canonical format.

---

**Input**: An aggregate identifier in the form `<bounded-context>/<aggregate>` (kebab-lowercase). Optional: `--from <path-to-md>` to import rules from an external markdown source.

**Steps**

1. **Run the helper script**

   ```bash
   npx tsx scripts/business-rules/document.ts <bc>/<aggregate>
   ```

   Or with imported source material:
   ```bash
   npx tsx scripts/business-rules/document.ts <bc>/<aggregate> --from path/to/word-export.md
   ```

   The script:
   - Validates the aggregate exists (`cliter/<bc>/<aggregate>.aurora.yaml`).
   - Creates a frontmatter scaffold at `cliter/<bc>/business-rules/<aggregate>.md` if it does not exist.
   - Lists every source file you (the LLM) should consult.
   - Prints guidance for the analysis step.

2. **Analyse the sources** (this is where the LLM does the work)

   Read in this order:
   - The aggregate's `*.aurora.yaml` to learn states, relationships, fields.
   - The bounded context's `CONTEXT.md` (if it exists) for high-level flow.
   - Domain code: services, handlers, sagas under `backend/src/@app/<bc>/<aggregate>/` and `backend/src/@api/<bc>/<aggregate>/`.
   - Frontend logic: validators, guards, custom logic under `frontend/src/app/modules/admin/apps/<bc>/<aggregate>/`.
   - Tests (`*.spec.ts`).
   - The `--from` material, if provided.

3. **Identify candidate rules**

   For each behavior implicit in the code, classify:
   - **validation** — pre-condition on a command (e.g., "no se puede X si Y").
   - **cascade** — state-machine effect on this or other aggregates.
   - **derived** — invariant computed from other data (totals, counts).
   - **policy** — business policy (limits, ratios, exceptions).

4. **Draft each rule** following the canonical template in `docs/business-rules/README.md`:
   - ID: `BR-<BC-CORTO>-<AGG-CORTO>-<NNN>` (next sequential per aggregate; never reuse a derogated identifier).
   - Title in Spanish, short and specific.
   - Metadata table (Tipo, Estado, Severidad, Origen). New retro-documented rules: `Estado: active`, `Origen: retro-documentada desde código existente`.
   - Enunciado in Spanish.
   - Diagrama de cascada (if `cascade`).
   - Casos exhaustivos in a markdown table. Mark `[VERIFICAR]` for any case not unambiguously derivable from code; mark `[ASUNCIÓN]` for assumed-true preconditions.
   - Implementa: cite real paths and lines (e.g., `backend/.../foo.service.ts:42`).
   - Tests: cite real test files and test names.
   - Reglas relacionadas: any cross-aggregate links.

5. **Confirm with the user before writing**

   Present the candidate rules in summary form (ID + title + Tipo + Severidad), and ask the user to confirm or amend each one. **Do NOT write to the file before getting confirmation**, especially if there are existing rules to avoid accidental clobber.

6. **Persist and validate**

   After confirmation:
   - Write the rules into `cliter/<bc>/business-rules/<aggregate>.md`.
   - Run `pnpm br:generate` to refresh the index.
   - Run `pnpm br:validate` to ensure structural integrity.
   - Commit with `chore(business-rules): document <bc>/<aggregate>`.

**Guardrails**

- Spanish prose, English identifiers, bilingual keywords. Do NOT translate any of it (`do not harmonize`).
- If the aggregate's code uses concepts that span multiple bounded contexts (e.g., a permission check from `iam`), include the additional BC in `bounded_contexts` (plural). Add an apuntador in the affected BC's catalog file.
- For the Word/markdown import (`--from`): treat the source as candidate material, not as authoritative. Verify each rule against actual code; add `[VERIFICAR]` on any divergence.
- Don't invent cases that aren't grounded in code or in the imported source. Better to leave a `[VERIFICAR]` than to fabricate a row in the case table.
