# Search tasks

**Advanced task filtering with custom GraphQL where clauses and dynamic ordering**
Supports flexible filtering across any task field — including nested relations
such as `taskType` and `job` — using GraphQL-style `where` clauses, with
pagination and dynamic ordering.
**Common filter examples (pass in the `where` field):**
- By task type ID:   `{ "taskTypeId": { "_eq": 123 } }`
- By task type code: `{ "taskType": { "code": { "_eq": "PREP" } } }`
- By client:         `{ "job": { "clientId": { "_eq": 456 } } }`
- Start date range:  `{ "startDate": { "_gte": "2024-01-01", "_lte": "2024-12-31" } }`
- Due date range:    `{ "dueDate": { "_gte": "2024-01-01", "_lte": "2024-12-31" } }`
- By assignee:       `{ "assigneeStaffId": { "_eq": 789 } }`
- Combined:          `{ "_and": [ { "taskType": { "code": { "_eq": "PREP" } } }, { "assigneeStaffId": { "_eq": 789 } } ] }`

**Real Example:**

```bash
curl --location 'https://{{host}}/v1/tasks/search' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data '{
  "pageSize": 25,
  "page": 0,
  "where": {
    "_and": [
      { "taskType": { "code": { "_eq": "PREP" } } },
      { "assigneeStaffId": { "_eq": 789 } }
    ]
  },
  "orderBy": [
    { "dueDate": "asc" }
  ]
}'
```

Endpoint: POST /v1/tasks/search
Version: 1.0.0
Security: BearerAuth

## Request fields (application/json):

  - `pageSize` (integer)
    Maximum number of tasks to return
    Example: 25

  - `page` (integer)
    Offset (number of records to skip) for pagination
    Example: 0

  - `where` (object)
    GraphQL-style where clause for filtering. Supports operators such as `_eq`, `_neq`, `_in`, `_nin`, `_ilike`, `_gte`, `_lte`, and logical combinators `_and`, `_or`, `_not`. Nested relations `taskType` and `job` can be filtered inline.
    Example: {"_and":[{"taskType":{"code":{"_eq":"PREP"}}},{"assigneeStaffId":{"_eq":789}}]}

  - `orderBy` (array)
    Dynamic ordering specifications. Each element maps a field name to `"asc"` or `"desc"`. Defaults to `[{ "id": "asc" }]`.
    Example: [{"dueDate":"asc"}]

## Response 200 fields (application/json):

  - `tasks` (array)
    List of tasks matching the filter criteria

  - `tasks.id` (integer)
    Unique identifier of the task
    Example: 456

  - `tasks.name` (string)
    Task name
    Example: Q4 Financial Statement Review

  - `tasks.overrideName` (string)
    Optional name that overrides the default task name
    Example: null

  - `tasks.status` (string)
    Current status of the task
    Example: IN_PROGRESS

  - `tasks.pmsRef` (string)
    Practice management system reference identifier
    Example: TASK-001

  - `tasks.jobId` (integer)
    ID of the job this task belongs to
    Example: 67890

  - `tasks.taskTypeId` (integer)
    ID of the task type
    Example: 1

  - `tasks.assigneeStaffId` (integer)
    ID of the staff member assigned to this task
    Example: 789

  - `tasks.startDate` (string)
    Actual start date of the task
    Example: 2024-10-01

  - `tasks.dueDate` (string)
    Actual due date of the task
    Example: 2024-12-31

  - `tasks.targetStartDate` (string)
    Planned target start date
    Example: 2024-09-15

  - `tasks.targetDueDate` (string)
    Planned target due date
    Example: 2024-12-15

  - `tasks.estimatedHours` (number)
    Estimated hours to complete the task
    Example: 40

  - `tasks.completedAt` (string)
    Timestamp when the task was completed
    Example: null

  - `tasks.description` (string)
    Detailed description of the task
    Example: Review and analyse Q4 financial statements

  - `tasks.ordinal` (integer)
    Display order position of the task
    Example: 1

  - `tasks.parentTaskId` (integer)
    ID of the parent task if this is a subtask
    Example: null

  - `tasks.isCreatedByAiwyn` (boolean)
    Whether this task was created by Aiwyn
    Example: false

  - `tasks.isManagedByAiwyn` (boolean)
    Whether this task is managed by Aiwyn
    Example: false

  - `tasks.createdAt` (string)
    Timestamp when the task was created
    Example: 2024-09-01T08:00:00Z

  - `tasks.updatedAt` (string)
    Timestamp when the task was last updated
    Example: 2024-10-01T09:30:00Z

  - `tasks.taskType` (object)
    The task type associated with this task

  - `tasks.taskType.id` (integer)
    Example: 1

  - `tasks.taskType.code` (string)
    Example: PREP

  - `tasks.taskType.display` (string)
    Example: Tax Preparation

  - `tasks.taskType.billable` (boolean)
    Example: true

  - `tasks.taskType.taxable` (boolean)
    Example: false

  - `tasks.taskType.active` (boolean)
    Example: true

  - `tasks.assigneeStaff` (object)
    The staff member assigned to this task

  - `tasks.assigneeStaff.id` (integer)
    Example: 789

  - `tasks.assigneeStaff.firstName` (string)
    Example: Jane

  - `tasks.assigneeStaff.lastName` (string)
    Example: Doe

  - `tasks.assigneeStaff.email` (string)
    Example: jane.doe@firm.com

  - `tasks.job` (object)
    The job this task belongs to

  - `tasks.job.id` (integer)
    Example: 67890

  - `total` (object)
    Aggregate count matching the filter (ignores pagination)

  - `total.aggregate` (object)

  - `total.aggregate.count` (integer)
    Total number of tasks matching the where clause
    Example: 84

