# Model Implementation

## Context

Module: {{MODULE_NAME}}
Model doc: {{MODEL_DOC}}

## Instructions

Implement a database model based on the documentation.

1. Read the model doc at the path above
2. Read existing models in `{{MODULES_ROOT}}/{{MODULE_NAME}}/db/` for patterns
3. Implement the model in `{{MODULES_ROOT}}/{{MODULE_NAME}}/db/<model-name>.ts`

## Implementation Rules

**Read these references before implementing:**

- [Model patterns](models.md) — factory function, generics, stateful enums
- [Field builder API](db-field-api.md) — available field types, optional fields, no `.nullable()` / `db.json()`
- [Database relations](db-relations.md) — `.relation()` for foreign keys
- [Cross-module dependencies](cross-module-dependency.md) — DB type injection

### Key Patterns

1. **Factory function**: `export function create<Model>Type<const F extends Record<string, TailorAnyDBField> = Record<string, never>>(params: { ... })`
2. **Timestamps**: Always include `db.fields.timestamps()`
3. **Descriptions**: Add `.description()` on every field
4. **Relations**: Use `.relation()` instead of plain `db.uuid()` for foreign keys
5. **Stateful models**: If a `.lifecycle.generated.ts` exists for the model, use `lifecycle.states` for the status enum

### From Doc to Code

| Doc Element        | Code Element                              |
| ------------------ | ----------------------------------------- |
| Fields table       | `db.string()`, `db.int()`, etc.           |
| Required fields    | Field without `{ optional: true }`        |
| Optional fields    | `db.string({ optional: true })`           |
| Status/state enum  | `db.enum(lifecycle.states)` from `.lifecycle.generated.ts` |
| Relationships      | `.relation()` with type and toward config |
| Unique constraints | `.unique()` on field or `.indexes({ unique: true })` for composite |

### Concrete Example

```typescript
import {
  db,
  type TailorAnyDBField,
  type TailorAnyDBType,
  unsafeAllowAllGqlPermission,
  unsafeAllowAllTypePermission,
} from "@tailor-platform/sdk";
import { company as companyStub } from "../lib/_db_deps";

import { orderLifecycle } from "./order.lifecycle.generated";

export interface CreateOrderTypeParams<F extends Record<string, TailorAnyDBField>> {
  fields?: F;
  companyType: TailorAnyDBType;
}

export function createOrderType<const F extends Record<string, TailorAnyDBField>>(
  params: CreateOrderTypeParams<F>,
) {
  return db
    .type("Order", {
      // Required string with unique constraint
      code: db.string().unique().description("Order code"),
      name: db.string().description("Order name"),
      // Optional string
      note: db.string({ optional: true }).description("Optional note"),
      // Enum — derived from generated lifecycle
      status: db.enum(orderLifecycle.states).description("Lifecycle status"),
      // Date
      orderDate: db.date().description("Order document date"),
      // Integer
      lineCount: db.int({ optional: true }).description("Number of lines"),
      // Decimal
      totalAmount: db.decimal().description("Total order amount"),
      // Boolean
      isUrgent: db.bool().description("Whether this order is urgent"),
      // Relation (n-1 foreign key)
      companyId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: params.companyType },
          backward: "orders",
        })
        .description("Foreign key to Company"),
      // Nested object (array)
      snapshotLines: db
        .object(
          {
            kind: db.string({ optional: true }),
            amount: db.decimal({ optional: true }),
          },
          { optional: true, array: true },
        )
        .description("Snapshotted line items"),
      // Custom fields spread + timestamps
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(unsafeAllowAllTypePermission)
    .gqlPermission(unsafeAllowAllGqlPermission);
}

// Default instance with stubs for cross-module types
export const order = createOrderType({ companyType: companyStub });
```

## Output

Write the model file to `{{MODULES_ROOT}}/{{MODULE_NAME}}/db/<model-name>.ts`.
Follow existing patterns in the module's `db/` directory.
