# Command Implementation

## Context

Module: {{MODULE_NAME}}
Command doc: {{COMMAND_DOC}}

## Instructions

Implement a command with tests using TDD.

1. Read the command doc at the path above
2. Read the generated shell at `{{MODULES_ROOT}}/{{MODULE_NAME}}/command/<name>.generated.ts`
3. Read existing commands in `{{MODULES_ROOT}}/{{MODULE_NAME}}/command/` for patterns
4. Implement in this order: fixtures → tests → implementation

## Implementation Rules

**Read these references before implementing:**

- [Command patterns](../../erp-kit-shared/references/commands.md) — run function, custom fields, CQRS
- [Testing patterns](../../erp-kit-shared/references/testing.md) — mock DB, fixtures, test structure

### Step 1: Test Fixtures

Add fixtures to `{{MODULES_ROOT}}/{{MODULE_NAME}}/testing/fixtures.ts`:

- Use fixed IDs: `"entity-1"`, `"entity-2"`
- Create minimal valid entities for the command under test
- Include fixtures for related entities if needed

### Step 2: Write Tests

Create `{{MODULES_ROOT}}/{{MODULE_NAME}}/command/<name>.test.ts`:

- Test every process flow branch from the doc
- Test every error scenario from the doc
- Test idempotent paths if applicable
- Use `createMockDb<DB>()` for mock database
- Assert on result type (ok/err) and values

### Step 3: Implement

Create `{{MODULES_ROOT}}/{{MODULE_NAME}}/command/<name>.ts`:

- Export a `run` function
- Generated shell wraps with `defineCommand(permissions.xxx, run)`
- Pattern: validate → query → mutate
- Generic `CF` for custom fields support
- State transition commands: use `executeTransition` for simple transitions (status change only), `lifecycle.tryTransition` for transitions with side effects

### From Doc to Code

| Doc Element      | Code Element                                    |
| ---------------- | ----------------------------------------------- |
| Business rules   | Validation checks in `run` function             |
| Error scenarios  | Import from `errors.generated.ts`, return `err` |
| Result checking  | Check `result.ok` on command calls; ok-only queries use `.value` directly |
| Process flow     | Implementation steps in `run` function          |
| Input parameters | `Input` interface (exported)                    |
| Permissions      | Generated in `permissions.generated.ts`         |

## Output

Write files:

- `{{MODULES_ROOT}}/{{MODULE_NAME}}/testing/fixtures.ts` (add fixtures, don't overwrite existing)
- `{{MODULES_ROOT}}/{{MODULE_NAME}}/command/<name>.test.ts`
- `{{MODULES_ROOT}}/{{MODULE_NAME}}/command/<name>.ts`
