> ## 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.

# Task

> A Task represents a discrete unit of work within a workspace — it can be user-created, agent-created, or system-seeded as part of an onboarding or provider-scor

A Task represents a discrete unit of work within a workspace — it can be user-created, agent-created, or system-seeded as part of an onboarding or provider-scoring pipeline. Tasks belong to a single workspace, may be assigned to a Person, and may form a parent-child hierarchy (a task may have one parent task and many subtasks). They carry a rich status lifecycle, typed enums for executor and source, optional plan/step/scoring/subworkspace-candidate metadata in a JSONB field, and a polymorphic references array that links them to invoices, companies, people, documents, transactions, providers, or calendar months.

| Naming                          | Value       |
| ------------------------------- | ----------- |
| Object                          | Task        |
| Resource type (JSON:API `type`) | `task`      |
| Collection / records root       | `tasks`     |
| REST base                       | `/v1/tasks` |
| Entity class                    | `Task`      |

## API operations

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

## Data model

### Attributes

| Field                    | Type                                      | Required | Constraints                                                                                                                                                                                                                                                                                                                                         | Allowed values                                                                                                                                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------ | ----------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| task\_id                 | string, UUID, system                      | ✅ Yes    | unique; generated by gen\_random\_uuid() on INSERT                                                                                                                                                                                                                                                                                                  | —                                                                                                                                                                 | Public stable identifier for the task. Never changes after creation.                                                                                                                                                                                                                                                                                                                                                                                                           |
| title                    | string                                    | ✅ Yes    | text; no length limit enforced at DB level                                                                                                                                                                                                                                                                                                          | —                                                                                                                                                                 | Short human-readable label for the task, shown in the UI and chat cards.                                                                                                                                                                                                                                                                                                                                                                                                       |
| description              | string                                    | ⚪ No     | text; nullable                                                                                                                                                                                                                                                                                                                                      | —                                                                                                                                                                 | Optional longer prose explanation of what the task requires and why.                                                                                                                                                                                                                                                                                                                                                                                                           |
| status                   | string (enum)                             | ✅ Yes    | default = 'open'; backed by native PG enum task\_status\_enum; partial unique index uniq\_tasks\_active\_provider\_company fires only on status IN ('open','ice\_log','blocked')                                                                                                                                                                    | ice\_log, open, in\_progress, done, blocked, cancelled, archived                                                                                                  | Lifecycle state of the task. ice\_log = surfaced but not yet actionable; archived = closed but kept for audit.                                                                                                                                                                                                                                                                                                                                                                 |
| executor\_type           | string (enum)                             | ✅ Yes    | NOT NULL; backed by native PG enum executor\_type\_enum                                                                                                                                                                                                                                                                                             | human, system                                                                                                                                                     | Whether the task is intended for a human actor or executed entirely by the system/agent pipeline.                                                                                                                                                                                                                                                                                                                                                                              |
| source                   | string (enum)                             | ✅ Yes    | default = 'user'; backed by native PG enum task\_source\_enum                                                                                                                                                                                                                                                                                       | user, agent                                                                                                                                                       | Whether the task was created by a human user or autonomously by an AI agent.                                                                                                                                                                                                                                                                                                                                                                                                   |
| priority                 | string (enum)                             | ⚪ No     | nullable; default = 'medium'; backed by native PG enum task\_priority\_enum                                                                                                                                                                                                                                                                         | low, medium, high, critical                                                                                                                                       | Urgency level of the task, used to sort and filter the task list in the UI.                                                                                                                                                                                                                                                                                                                                                                                                    |
| confidence\_score        | number (decimal)                          | ⚪ No     | nullable; columnType numeric(3,2); range 0.00-1.00                                                                                                                                                                                                                                                                                                  | —                                                                                                                                                                 | Agent-assigned confidence that the task is relevant and actionable for this workspace. Higher means more certain.                                                                                                                                                                                                                                                                                                                                                              |
| token\_reward            | integer                                   | ⚪ No     | nullable; integer                                                                                                                                                                                                                                                                                                                                   | —                                                                                                                                                                 | Gamification reward tokens awarded to the user upon completing this task. Sourced from the associated TaskTemplate or set by the pipeline.                                                                                                                                                                                                                                                                                                                                     |
| due\_date                | datetime                                  | ⚪ No     | nullable; no DB-level CHECK                                                                                                                                                                                                                                                                                                                         | —                                                                                                                                                                 | Optional deadline after which the task is considered overdue. Displayed in the task card and used for sorting.                                                                                                                                                                                                                                                                                                                                                                 |
| visible\_date            | datetime                                  | ⚪ No     | nullable; no DB-level CHECK                                                                                                                                                                                                                                                                                                                         | —                                                                                                                                                                 | Date before which the task should not be surfaced to the user (deferred visibility). Used by the scoring pipeline to schedule tasks for future monthly-close cycles.                                                                                                                                                                                                                                                                                                           |
| references               | jsonb (array of TaskReference objects)    | ✅ Yes    | defaults to \[]; GIN index idx\_tasks\_references\_gin (jsonb\_path\_ops) for fast dedup lookups                                                                                                                                                                                                                                                    | Array of \{ type: invoice\|company\|person\|document\|transaction\|provider\|month, id: string, label: string }                                                   | Polymorphic reference list linking the task to one or more domain entities. Drives context in the chat card and CTA routing. The first provider-typed entry is denormalized into provider\_ref\_id; the first company-typed entry into company\_ref\_id.                                                                                                                                                                                                                       |
| provider\_ref\_id        | string                                    | ⚪ No     | nullable; varchar(36); denormalized from references\[0 where type='provider'].id; participates in partial unique index uniq\_tasks\_active\_provider\_company on (workspace\_pk, provider\_ref\_id, company\_ref\_id) WHERE deleted\_at IS NULL AND status IN ('open','ice\_log','blocked') AND both ref\_ids NOT NULL AND parent\_task\_pk IS NULL | —                                                                                                                                                                 | Denormalized first provider reference id extracted from the references array. Populated at task creation by TaskService.createTask. Enables O(1) dedup guard preventing duplicate root scoring tasks for the same workspace x provider x company triplet.                                                                                                                                                                                                                      |
| company\_ref\_id         | string                                    | ⚪ No     | nullable; varchar(36); denormalized from references\[0 where type='company'].id; co-participant in partial unique index uniq\_tasks\_active\_provider\_company                                                                                                                                                                                      | —                                                                                                                                                                 | Denormalized first company reference id extracted from the references array. Populated at task creation by TaskService.createTask alongside provider\_ref\_id.                                                                                                                                                                                                                                                                                                                 |
| history                  | jsonb (array of TaskHistoryEntry objects) | ✅ Yes    | defaults to \[]                                                                                                                                                                                                                                                                                                                                     | Array of \{ action: created\|status\_changed\|assigned\|comment, at: ISO8601, by?: string, by\_type: human\|system, from?: string, to?: string, detail?: string } | Append-only audit log of state transitions and comments on this task. Each entry records who did what and when.                                                                                                                                                                                                                                                                                                                                                                |
| plan\_meta               | jsonb (discriminated union on 'kind')     | ⚪ No     | nullable. Partial unique index uq\_tasks\_subworkspace\_candidate\_dedup on (workspace\_pk, plan\_meta->>'dedup\_key') WHERE deleted\_at IS NULL AND plan\_meta->>'kind' = 'subworkspace-candidate' AND plan\_meta->>'dedup\_key' IS NOT NULL.                                                                                                      | kind: plan \| step \| scoring \| mail-connect \| connect-extension \| connect-tools-parent \| subworkspace-candidate                                              | Optional metadata blob whose shape is discriminated by the 'kind' field. plan = agentic plan phases. step = individual step within a plan. scoring = provider-scoring signals and CTA route. mail-connect = connect-email fallback gate. connect-extension = Chrome extension install sub-task. connect-tools-parent = lazy parent for provider-connection subtasks. subworkspace-candidate = WAS-projection, detection signals, and dedup\_key for child workspace discovery. |
| score                    | number (decimal)                          | ⚪ No     | nullable; columnType numeric(8,2)                                                                                                                                                                                                                                                                                                                   | —                                                                                                                                                                 | Computed relevance or urgency score assigned by the scoring pipeline (0-1000+ scale). Used to order tasks in the UI surface.                                                                                                                                                                                                                                                                                                                                                   |
| done\_at                 | datetime                                  | ⚪ No     | nullable; no DB trigger; set by service layer                                                                                                                                                                                                                                                                                                       | —                                                                                                                                                                 | Timestamp when the task transitioned to status=done. Set by the service layer on completion.                                                                                                                                                                                                                                                                                                                                                                                   |
| conversation\_thread\_id | string, UUID                              | ⚪ No     | nullable; UuidType; soft reference only (no FK constraint)                                                                                                                                                                                                                                                                                          | —                                                                                                                                                                 | UUID of the chat conversation thread associated with this task. Allows the AI to link back to the thread context. No FK cascade — deleting the conversation does not affect the task.                                                                                                                                                                                                                                                                                          |
| created\_at              | datetime, system                          | ✅ Yes    | set on INSERT via MikroORM onCreate lifecycle; not nullable                                                                                                                                                                                                                                                                                         | —                                                                                                                                                                 | Timestamp when the task row was created.                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| updated\_at              | datetime, system                          | ⚪ No     | set on INSERT (onCreate) and updated on every UPDATE (onUpdate) via MikroORM lifecycle                                                                                                                                                                                                                                                              | —                                                                                                                                                                 | Timestamp of the last modification to this task row.                                                                                                                                                                                                                                                                                                                                                                                                                           |
| deleted\_at              | datetime, system                          | ⚪ No     | nullable; soft-delete sentinel; all active queries filter deleted\_at IS NULL; both partial unique indexes include deleted\_at IS NULL in their WHERE clause so hard-deletes release dedup slots                                                                                                                                                    | —                                                                                                                                                                 | Soft-delete timestamp. When set, the task is logically deleted and excluded from all active queries.                                                                                                                                                                                                                                                                                                                                                                           |

### Relationships

| Name         | Type                    | Required | Description                                                                                                                                                                                                                                                                                                                   |
| ------------ | ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| workspace    | to-one (workspace)      | ✅ Yes    | The workspace this task belongs to. deleteRule = 'cascade' — deleting the workspace hard-deletes all its tasks. Every query must scope to this relationship. Composite index idx\_tasks\_workspace\_status covers (workspace\_pk, status) for efficient status-filtered list queries.                                         |
| template     | to-one (task\_template) | ⚪ No     | Optional reference to the TaskTemplate that spawned or defines this task (title, markdown content, action type, token reward). deleteRule = 'set null' — deleting a template leaves tasks intact but unlinked. Template-less tasks are common for agent-generated or platform-seeded rows.                                    |
| parent\_task | to-one (task)           | ⚪ No     | Self-referential parent for hierarchical task trees. A root task has parent\_task = null. deleteRule = 'set null' — deleting a parent orphans its children rather than cascade-deleting them. The partial unique index uniq\_tasks\_active\_provider\_company only applies to root tasks (parent\_task\_pk IS NULL).          |
| subtasks     | to-many (task)          | —        | Inverse of parent\_task. Collection of child tasks nested under this task. The composite composite\_subtasks\_list (display\_type: relation\_list, sort\_proxy: subtasks\_aggregate.min.created\_at) in composites.yml surfaces subtask task\_id, title, status, and due\_date as a relation\_list cell in the records table. |
| assigned\_to | to-one (people)         | ⚪ No     | The Person to whom the task is assigned for action. deleteRule = 'set null'. The composite assigned\_to.composite\_avatar\_fullname (display\_type: people\_avatar\_name) in composites.yml surfaces person\_id, avatar URL, and full\_name as a composite cell in the records table.                                         |
| created\_by  | to-one (people)         | ⚪ No     | The Person who created the task, when created by a human. Null for agent-created or system-seeded tasks. deleteRule = 'set null'.                                                                                                                                                                                             |

### System-computed

* task\_id is generated by gen\_random\_uuid() at INSERT via MikroORM defaultRaw; unique constraint enforced at DB level.
* created\_at is set by MikroORM onCreate lifecycle hook to new Date(); never subsequently updated.
* updated\_at is set by MikroORM onCreate and refreshed on every UPDATE via onUpdate lifecycle hook.
* deleted\_at is the soft-delete sentinel. All active queries must filter deleted\_at IS NULL. Both partial unique indexes (uniq\_tasks\_active\_provider\_company and uq\_tasks\_subworkspace\_candidate\_dedup) include deleted\_at IS NULL so hard-deleting a row releases its dedup slot.
* status defaults to 'open' (TaskStatusEnum.OPEN) at entity construction; the native PG enum task\_status\_enum enforces allowed values at the DB level.
* source defaults to 'user' (TaskSourceEnum.USER); overridden to 'agent' by the scoring and onboarding pipelines.
* priority defaults to 'medium' (TaskPriorityEnum.MEDIUM); nullable so it can be intentionally unset.
* references defaults to \[] (empty array). The first provider-typed entry is extracted to provider\_ref\_id and the first company-typed entry to company\_ref\_id by TaskService.createTask. These two denormalized columns must stay in sync with the references array via service-layer discipline (no DB trigger enforces this).
* history defaults to \[] (empty array). Entries are appended by the service layer on every state transition (status\_changed, assigned, comment). No DB trigger; the service is the sole writer.
* Partial unique index uniq\_tasks\_active\_provider\_company on (workspace\_pk, provider\_ref\_id, company\_ref\_id) WHERE deleted\_at IS NULL AND status IN ('open','ice\_log','blocked') AND provider\_ref\_id IS NOT NULL AND company\_ref\_id IS NOT NULL AND parent\_task\_pk IS NULL. Closes the concurrent-worker dedup race for root scoring tasks. Sub-tasks (parent\_task\_pk IS NOT NULL) are excluded by design.
* Partial unique index uq\_tasks\_subworkspace\_candidate\_dedup on (workspace\_pk, (plan\_meta->>'dedup\_key')) WHERE deleted\_at IS NULL AND plan\_meta->>'kind' = 'subworkspace-candidate' AND plan\_meta->>'dedup\_key' IS NOT NULL. Prevents re-emission of duplicate subworkspace-candidate tasks for the same canonical identity. CANCELLED rows are still covered; only hard-deleted rows release the slot.
* Composite index idx\_tasks\_workspace\_status on (workspace\_pk, status) for efficient status-filtered workspace list queries.
* GIN index idx\_tasks\_references\_gin on references JSONB column (jsonb\_path\_ops) for fast reference-type filter and dedup lookups.
* plan\_meta is a discriminated-union JSONB blob. The 'kind' discriminant determines the valid shape. The rendering layer narrows on plan\_meta.kind to select the correct chat card or CTA component.
* done\_at is set by the service layer when transitioning status to 'done'; it is not a DB-generated column.
* conversation\_thread\_id is a soft UUID reference to a ChatConversation; there is no FK constraint so deleting the conversation does not affect the task.

## Example

```json theme={null}
{
  "data": {
    "type": "task",
    "id": "d4f1c7b2-3a9e-4f08-91c3-8e20b5f6a012",
    "attributes": {
      "title": "Connect Stripe to import missing invoices",
      "description": "We detected 14 open transactions from Stripe that have no matching invoice. Connect the Stripe provider to auto-import them.",
      "status": "open",
      "executor_type": "human",
      "source": "agent",
      "priority": "high",
      "confidence_score": "0.88",
      "token_reward": "50",
      "due_date": "2026-06-15T00:00:00.000Z",
      "visible_date": "2026-06-01T00:00:00.000Z",
      "score": "940.00",
      "done_at": null,
      "conversation_thread_id": null,
      "provider_ref_id": "a3f8c1d2-1111-4b0c-9abc-000000000001",
      "company_ref_id": "b7e2a5c4-2222-4c1d-8def-000000000002",
      "references": [
        { "type": "provider", "id": "a3f8c1d2-1111-4b0c-9abc-000000000001", "label": "Stripe" },
        { "type": "company",  "id": "b7e2a5c4-2222-4c1d-8def-000000000002", "label": "Stripe Payments Europe Ltd" }
      ],
      "history": [
        { "action": "created", "at": "2026-06-02T08:30:00.000Z", "by": null, "by_type": "system" },
        { "action": "assigned", "at": "2026-06-02T09:00:00.000Z", "by": "usr_human_01", "by_type": "human", "to": "Alice Martin" }
      ],
      "plan_meta": {
        "kind": "scoring",
        "signals": { "open_transactions": 14, "total_amount_eur": 12800, "dominant_currency": "EUR" },
        "route": { "action_type": "connect_provider" }
      },
      "created_at": "2026-06-02T08:30:00.000Z",
      "updated_at": "2026-06-02T09:00:00.000Z",
      "deleted_at": null
    },
    "relationships": {
      "workspace": { "data": { "type": "workspace", "id": "9f3a4b7c-0001-4e2a-b000-aabbccddeeff" } },
      "template": { "data": null },
      "parent_task": { "data": null },
      "subtasks": { "data": [] },
      "assigned_to": { "data": { "type": "people", "id": "c8d1f9e0-3333-4d2e-9e00-000000000003" } },
      "created_by": { "data": null }
    }
  }
}
```

<sub>Source: `apps/api/src/database/entities/Task.ts` · domain: workspace · tier: Activity</sub>
