> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wellapp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ExtractPrompt

> ExtractPrompt stores named, versioned AI extraction prompt templates that drive the document-extraction pipeline when ingesting invoices and documents

ExtractPrompt stores named, versioned AI extraction prompt templates that drive the document-extraction pipeline when ingesting invoices and documents. Each record is scoped to a `type` (e.g. the extraction category), carries the raw prompt text, a monotone `version` counter, an `is_active` flag, and an `is_default` flag marking the system-wide fallback. Records are either workspace-scoped (a workspace-level customisation) or global (no workspace FK, `is_default = true`). The entity is owned exclusively by the extraction pipeline and seed layer; no user-facing PATCH endpoint exists.

| Naming                          | Value                             |
| ------------------------------- | --------------------------------- |
| Object                          | ExtractPrompt                     |
| Resource type (JSON:API `type`) | `extract_prompt`                  |
| Collection / records root       | — <sub>(not a records root)</sub> |
| REST base                       | `/v1/extract-prompts`             |
| Entity class                    | `ExtractPrompt`                   |

<Note>
  **Internal object.** Not currently exposed on the public REST API. The operations below describe the intended contract.
</Note>

## API operations

| Operation | Method & path                     | Status     |
| --------- | --------------------------------- | ---------- |
| List      | `GET /v1/extract-prompts`         | 🟡 Planned |
| Retrieve  | `GET /v1/extract-prompts/{id}`    | 🟡 Planned |
| Create    | `POST /v1/extract-prompts`        | 🟡 Planned |
| Update    | `PATCH /v1/extract-prompts/{id}`  | 🟡 Planned |
| Delete    | `DELETE /v1/extract-prompts/{id}` | 🟡 Planned |

## Data model

### Attributes

| Field       | Type                      | Required | Constraints                                                                                           | Allowed values                                                                                               | Description                                                                                                                                                                                                                                                                                  |
| ----------- | ------------------------- | -------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string (UUID) — 🔒 system | ✅ Yes    | PK; gen\_random\_uuid() default; immutable after creation                                             | Any valid UUID v4                                                                                            | Public stable identifier for the prompt record. Exposed as `id` in JSON:API; backed by the `pk` UUID column.                                                                                                                                                                                 |
| type        | string                    | ✅ Yes    | varchar(100); NOT NULL; single-column index; composite indexes (type, is\_active) and (type, version) | Free-form string — conventionally an extraction category slug such as `invoice`, `receipt`, `bank_statement` | Categorisation key grouping prompt versions under a logical extraction pipeline stage. Used by the extraction service to look up the current active prompt for a given category.                                                                                                             |
| prompt      | text                      | ✅ Yes    | PostgreSQL TEXT; NOT NULL; no length cap                                                              | Any non-null string (typically a multi-line AI system or user prompt)                                        | The raw LLM prompt text sent to the extraction model. May contain field-extraction instructions, output-format directives, or chain-of-thought scaffolding.                                                                                                                                  |
| version     | integer                   | ✅ Yes    | NOT NULL; DEFAULT 1; composite index (type, version); increments on each prompt revision              | Positive integer ≥ 1                                                                                         | Monotone version counter within a `type`. Allows the pipeline to track prompt iterations and roll back to a prior version by `is_active` flag manipulation.                                                                                                                                  |
| is\_active  | boolean                   | ✅ Yes    | NOT NULL; DEFAULT false; composite index (type, is\_active)                                           | true \| false                                                                                                | Indicates whether this is the currently active prompt for its `type`. The extraction service queries `type + is_active = true` to select the live prompt. Only one record per (type, workspace) combination should be active at a time — enforced by application logic, not a DB constraint. |
| is\_default | boolean                   | ✅ Yes    | NOT NULL; DEFAULT false                                                                               | true \| false                                                                                                | Marks the system-wide default prompt for its `type`. Default prompts have no `workspace` FK (`workspace = null`). Workspace-scoped prompts shadow the default when `is_active = true`.                                                                                                       |
| created\_at | timestamptz — 🔒 system   | ✅ Yes    | NOT NULL; set once via `onCreate` hook; never updated                                                 | ISO 8601 timestamp                                                                                           | Wall-clock UTC timestamp of row creation. Set automatically by MikroORM's `onCreate` lifecycle hook.                                                                                                                                                                                         |
| updated\_at | timestamptz — 🔒 system   | ⚪ No     | NULLABLE; set on first write via `onCreate`, refreshed on every subsequent write via `onUpdate`       | ISO 8601 timestamp or null                                                                                   | Wall-clock UTC timestamp of the last update. NULL until the first update after creation.                                                                                                                                                                                                     |

### Relationships

| Name      | Type               | Required        | Description                                                                                                                                                                                                                                                                                                                  |
| --------- | ------------------ | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| workspace | to-one (ManyToOne) | ⚪ No — nullable | Optional FK to the `workspaces` table (`workspace_pk` int). When NULL the prompt is a global default accessible to all workspaces. When set, the prompt is a workspace-level customisation that overrides the global default for that workspace's extraction pipeline. FK constraint: ON UPDATE CASCADE, ON DELETE SET NULL. |

### System-computed

* id (pk): generated by gen\_random\_uuid() at INSERT time; immutable.
* version: defaults to 1; incremented by the extraction pipeline or seed layer on prompt revision — not auto-incremented by the DB.
* is\_active: defaults to false; toggled by the pipeline when promoting a new prompt version.
* is\_default: defaults to false; set by the seed layer for system-wide baseline prompts.
* created\_at: set by MikroORM onCreate hook; never subsequently mutated.
* updated\_at: set by MikroORM onCreate hook on first persist; refreshed on every subsequent onUpdate event.
* workspace FK: set null automatically by the DB (ON DELETE SET NULL) when the parent workspace is deleted.

## Example

```json theme={null}
{
  "data": {
    "type": "extract_prompt",
    "id": "a3e1c7f2-84b0-4d2e-9c51-0f3b2d7e1a88",
    "attributes": {
      "type": "invoice",
      "prompt": "Extract the following fields from the invoice: issue_date, due_date, grand_total, tax_total, vendor_name, invoice_number. Return structured JSON only.",
      "version": 3,
      "is_active": true,
      "is_default": false,
      "created_at": "2025-09-21T17:50:44.000Z",
      "updated_at": "2025-10-14T09:12:03.000Z"
    },
    "relationships": {
      "workspace": {
        "data": { "type": "workspace", "id": "9f3b2d7e-1a88-4d2e-9c51-0f3b2d7e1a88" }
      }
    }
  }
}
```

<sub>Source: `/Users/maximechampoux/platform/apps/api/src/database/entities/ExtractPrompt.ts` · domain: ingestion · tier: Infrastructure</sub>
