# Module Directory Structure

This structure is automatically scaffolded by `erp-kit module init <name> <dir>`.

```
{module}/
├── db/           # Database models (one file per model)
├── executor/     # Async executors (record triggers, job functions)
├── command/      # Domain commands + tests (*.test.ts co-located)
│   ├── *.ts              # Hand-written business logic (run function)
│   ├── *.generated.ts    # Generated command shells (do not edit)
│   └── *.test.ts         # Tests
├── query/        # Read-only query handlers
│   ├── *.ts              # Hand-written custom queries
│   └── *.generated.ts    # Generated get/list queries (do not edit)
├── lib/
│   ├── errors.generated.ts    # Generated error classes (do not edit)
│   ├── permissions.generated.ts # Generated permissions (do not edit)
│   └── types.ts               # Hand-written types
├── testing/      # Test fixtures and helpers
├── generated/    # Auto-generated kysely types (do not edit)
├── index.ts      # Public exports
├── tailor.config.ts # Module config and generators
└── module.ts     # Module definition
```

## Rules

- `db/`: Only documentable model definitions, no helpers
- `executor/`: Async executors as factory functions (see executors.md)
- `command/`: Domain commands + co-located tests, no utilities
- `query/`: Read-only query handlers
- `lib/`: Generated errors/permissions + hand-written types
- `testing/`: Fixtures for tests only
- `.generated.ts` files are always overwritten — never edit them
- Run `pnpm generate` after modifying `db/` models

`db/`, `command/`, and `lib/` are required. `query/` is optional — a module can
be command-only (no read side), so `erp-kit verify` does not require it. Add
`query/` only when a feature implies a read operation.
