# Database Models

## Factory Function Pattern

Each model is a `createXType<const F>(params)` factory:

- Params interface generic: `F extends Record<string, TailorAnyDBField>`
- `fields?: F` — optional custom fields from parent modules
- Spread as `...(params.fields ?? {}) as F` to preserve type information
- Include `...db.fields.timestamps()`
- Use `.description()` for field docs
- Apply permissions at model level
- Export a default instance with stubs for cross-module types: `export const x = createXType({ unitType: unitStub })`
  - Cross-module type params are **required** — pass stubs from `lib/_db_deps.ts` explicitly
  - Never use `??` fallback to stubs inside the factory function body

## Stateful Model Enums

When a model has a State Transitions table in its doc, `erp-kit module generate code` produces a `db/<model>.lifecycle.generated.ts` file. Use its `.states` for the enum definition instead of hardcoding status arrays.

```typescript
import { productLifecycle } from "./product.lifecycle.generated";

// Good: derive enum from lifecycle — single source of truth
status: db.enum(productLifecycle.states).description("Lifecycle status"),

// Bad: hardcoded status array that can drift from the doc
const STATUSES = ["DRAFT", "ACTIVE", "ARCHIVED"] as const;
status: db.enum(STATUSES).description("Lifecycle status"),
```

- The lifecycle file is regenerated on every `generate code` run — never edit it
- The `<Model>Status` type exported from the lifecycle file gives the union type of all states
