{
  "openapi": "3.0.0",
  "paths": {
    "/v1/audit-events": {
      "get": {
        "operationId": "AuditController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "First calendar day of the window (inclusive). When omitted, the audit LISTING (GET /v1/audit-events) answers the last 90 days, ending at `to` or today; the CSV exports have no default and start at the beginning of the trail.",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Last calendar day of the window (inclusive).",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditEventPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Audit"
        ],
        "summary": "List audit events",
        "x-kelomo-capabilities": [
          "org.admin"
        ],
        "description": "**Capability:** `org.admin` — an API key must carry this in its scope."
      }
    },
    "/v1/attachments": {
      "post": {
        "operationId": "AttachmentsController_initiate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InitiateAttachmentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InitiateAttachmentResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Attachments"
        ],
        "summary": "Initiate an attachment upload",
        "description": "Two-phase upload: returns a presigned PUT URL; upload the bytes there, then call finalize. Authorization follows the owner object. An API key reaches attachments of commercial objects only (deal, invoice, project, purchase, quote, task); HR, absence and whistleblowing documents are never available over the API, whatever the key’s scope.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      },
      "get": {
        "operationId": "AttachmentsController_list",
        "parameters": [
          {
            "name": "ownerType",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ownerId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Attachments"
        ],
        "summary": "List the attachments of an owner object",
        "description": "Authorization follows the owner object. An API key reaches attachments of commercial objects only (deal, invoice, project, purchase, quote, task); HR, absence and whistleblowing documents are never available over the API, whatever the key’s scope.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/attachments/{id}/finalize": {
      "post": {
        "operationId": "AttachmentsController_finalize",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Attachments"
        ],
        "summary": "Finalize an uploaded attachment",
        "description": "Authorization follows the owner object. An API key reaches attachments of commercial objects only (deal, invoice, project, purchase, quote, task); HR, absence and whistleblowing documents are never available over the API, whatever the key’s scope.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/attachments/{id}/url": {
      "get": {
        "operationId": "AttachmentsController_downloadUrl",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentDownloadResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Attachments"
        ],
        "summary": "Get a short-lived download URL for an attachment",
        "description": "Authorization follows the owner object. An API key reaches attachments of commercial objects only (deal, invoice, project, purchase, quote, task); HR, absence and whistleblowing documents are never available over the API, whatever the key’s scope.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/attachments/{id}": {
      "delete": {
        "operationId": "AttachmentsController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Attachments"
        ],
        "summary": "Delete an attachment",
        "description": "Authorization follows the owner object. An API key reaches attachments of commercial objects only (deal, invoice, project, purchase, quote, task); HR, absence and whistleblowing documents are never available over the API, whatever the key’s scope.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/work-days": {
      "get": {
        "operationId": "DaysController_getRange",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayRangeResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s work days for a date range",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/work-days/{date}": {
      "get": {
        "operationId": "DaysController_getDay",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Get one of the caller’s work days with entries",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/work-days/{date}/entries": {
      "put": {
        "operationId": "DaysController_setEntries",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetWorkEntriesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Replace the caller’s work entries for a day",
        "description": "Full replacement of the day’s entries; idempotent. Draft days only — a confirmed day must be reopened first.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/work-days/{date}/proposal-dismissal": {
      "delete": {
        "operationId": "DaysController_restoreProposal",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Show the caller’s day proposal again",
        "description": "Clearing a day also stops that day proposing itself: it then reads as an empty frame with no pre-fill, no sources and no expected window, and carries `proposalDismissed: true`. This drops that dismissal, so the next read derives the proposal as usual. Idempotent — a day that was never cleared answers 204 unchanged. The day’s recorded entries are never touched: restoring a proposal is a view decision about an unrecorded day, not an edit of a record.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/balance": {
      "get": {
        "operationId": "DaysController_balance",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Get the caller’s current flex balance",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/staff-groups": {
      "get": {
        "operationId": "StaffGroupsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StaffGroupListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List staff groups",
        "x-kelomo-capabilities": [
          "worktime.supervise",
          "payroll.run"
        ],
        "description": "**Capability:** `worktime.supervise` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/me/work-days/{date}/confirm": {
      "post": {
        "operationId": "ConfirmationsController_confirm",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmWorkDayDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfirmWorkDayResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Confirm the caller’s work day",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/work-days/{date}/reopen": {
      "post": {
        "operationId": "ConfirmationsController_reopen",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Reopen the caller’s confirmed work day",
        "description": "Allowed only while the day is confirmed but not yet approved.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/work-days/{id}/approve": {
      "post": {
        "operationId": "ConfirmationsController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveWorkDayDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Approve a confirmed work day",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    },
    "/v1/work-days/approve-batch": {
      "post": {
        "operationId": "ConfirmationsController_approveBatch",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveWorkDaysBatchDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApproveWorkDaysBatchResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Approve several work days in one request",
        "description": "Batch form of the single-day approval: one request approves an explicit set of work-day ids, so a week never ends up half-approved by a client-side loop. The response reports the outcome per id.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/work-days/{id}/unapprove": {
      "post": {
        "operationId": "ConfirmationsController_unapprove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Withdraw the approval of a work day",
        "description": "Undo for a mis-approval: an approved day that has NOT been exported goes back to confirmed and any bank movement the approval made is reversed by a counter-entry, never by deletion. Emits workday.unapproved. An exported or already-confirmed day answers 409 day_not_approved — after export the only route is correct. The transition is guarded on the day’s status, so a retry cannot unapprove twice.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/work-days/return-batch": {
      "post": {
        "operationId": "ConfirmationsController_returnBatch",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnWorkDaysBatchDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReturnWorkDaysBatchResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Return several work days to the employee in one request",
        "description": "Batch form of the single-day return (the twin of approve-batch): one request returns an explicit set of confirmed work-day ids to draft with one shared reason, so a week never ends up half-returned by a client-side loop. At most 500 ids. Each day is its own transaction and emits its own workday.returned — N days produce N events, not one — and days that can no longer act are reported per id in `skipped` instead of failing the batch.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/work-days/{id}/return": {
      "post": {
        "operationId": "ConfirmationsController_returnToDraft",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnWorkDayDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Return a work day to the employee for correction",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    },
    "/v1/work-days/{id}/correct": {
      "post": {
        "operationId": "ConfirmationsController_correct",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnWorkDayDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Correct an approved or exported work day",
        "description": "The ONLY way to change a day that is past approval: the day returns to draft, a `correction` lifecycle event records who and why (reason required), bank movements from the approval are reversed by counter-entries, and the next payroll export picks the day up again with a correction marker — the batch already sent keeps its snapshot untouched. Nothing is edited in place. Emits workday.corrected. A day that is still draft or confirmed answers 409 day_not_correctable, a day inside a locked payroll period 409 period_locked, and a day whose hours are already invoiced 409 day_invoiced.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/webhooks": {
      "get": {
        "operationId": "WebhooksController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ],
        "description": "**Capability:** `integrations.manage` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "WebhooksController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpointDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateWebhookEndpointResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "Create a webhook endpoint",
        "description": "The signing secret is returned once, in this response only.\n\n**Capability:** `integrations.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ]
      }
    },
    "/v1/webhooks/{id}": {
      "patch": {
        "operationId": "WebhooksController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookEndpointDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "Update a webhook endpoint",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ],
        "description": "**Capability:** `integrations.manage` — an API key must carry this in its scope."
      },
      "delete": {
        "operationId": "WebhooksController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete a webhook endpoint",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ],
        "description": "**Capability:** `integrations.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/webhooks/{id}/rotate-secret": {
      "post": {
        "operationId": "WebhooksController_rotateSecret",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateWebhookSecretResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate a webhook endpoint’s signing secret",
        "description": "The new secret is returned once, in this response only.\n\n**Capability:** `integrations.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ]
      }
    },
    "/v1/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "WebhooksController_deliveries",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "List deliveries for a webhook endpoint",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ],
        "description": "**Capability:** `integrations.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver": {
      "post": {
        "operationId": "WebhooksController_redeliver",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "Redeliver a webhook delivery",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ],
        "description": "**Capability:** `integrations.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/webhooks/{id}/test": {
      "post": {
        "operationId": "WebhooksController_test",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test event to a webhook endpoint",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ],
        "description": "**Capability:** `integrations.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/integration-events": {
      "get": {
        "operationId": "IntegrationEventsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "event",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "quote.decided",
                "batch.created",
                "status_update.posted",
                "deal.won",
                "lead.created",
                "workday.approved",
                "export_batch.created",
                "export_batch.delivered",
                "export_batch.delivery_failed",
                "absence.submitted",
                "absence.decided",
                "shift.published",
                "invoice.issued",
                "invoice.credited",
                "invoice.dispatched",
                "invoice.delivered",
                "invoice.delivery_failed",
                "payment.recorded",
                "payment.allocated",
                "payment.imported",
                "invoice.overdue",
                "invoice.drafts_ready",
                "recurring_plan.run_completed",
                "batch.delivered",
                "workday.confirmed",
                "workday.returned",
                "workday.corrected",
                "workday.unapproved",
                "absence.cancelled",
                "absence.certificate_provided",
                "shift.changed",
                "open_shift.claimed",
                "open_shift.claim_decided",
                "shift_swap.proposed",
                "shift_swap.decided",
                "export_batch.cancelled",
                "payroll_period.locked",
                "payroll_period.lock_lifted",
                "member.created",
                "member.invited",
                "member.deactivated",
                "employment.terminated",
                "task.created",
                "task.status_changed",
                "task.approval_responded",
                "quote.sent",
                "quote.accepted",
                "deal.lost",
                "deal.stage_changed",
                "lead.converted",
                "intake.received",
                "change_order.approved",
                "project.created",
                "project.closed",
                "contact.anonymized",
                "lead.anonymized",
                "invoice.paid",
                "customer.created",
                "customer.updated",
                "project.updated",
                "member.updated",
                "shift.unpublished"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationEventPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Integration events"
        ],
        "summary": "List integration events",
        "description": "The same event log webhooks fan out. Asking for an event type outside the caller’s scope is refused (403), never a silently empty page.\n\n**Capability:** `integrations.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "integrations.manage"
        ]
      }
    },
    "/v1/webhook-events": {
      "get": {
        "operationId": "WebhookEventsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEventCatalogResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Webhooks"
        ],
        "summary": "List the webhook event catalogue",
        "description": "Every event Kelomo can deliver, with the capability a key must hold to subscribe and the JSON Schema (draft 2020-12) of the delivery’s `data` object. Deliveries carry identifiers, states and timestamps only — read the details you need through the API with the ids in the payload.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/entitlements": {
      "get": {
        "operationId": "CapabilitiesController_get",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeEntitlementsResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Get the caller’s module entitlements",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/trips": {
      "get": {
        "operationId": "TripsController_listMine",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "List the caller’s own trips",
        "description": "Cursor-paginated, newest first. Optional `from`/`to` (trip start) and `status` narrow the set.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      },
      "post": {
        "operationId": "TripsController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTripDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Create a draft trip for the caller",
        "description": "Creates the trip as a DRAFT and materialises its travel days, so the per-diem and night-allowance entitlement is computed immediately — read the trip back to see it. `startAt`/`endAt` are instants, because a per diem is counted in 24-hour periods from departure, not in calendar days. A foreign trip needs the tenant’s foreign-travel setting on and takes `countryCode` to seed the first leg. Nothing is claimed until the trip is submitted.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/trips/{id}": {
      "get": {
        "operationId": "TripsController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Get one of the caller’s trips",
        "description": "The whole claim: the trip, its travel days with the resolved per-diem level and night allowance, its country legs and its expense lines.\n\n**Capability:** none for the caller's own record — its authorisation is row-level. Reaching ANOTHER member's record with an API key additionally requires `worktime.supervise` or `hr.manage` in the key's scope.",
        "x-kelomo-capabilities": [],
        "x-kelomo-capabilities-beyond-self": [
          "worktime.supervise",
          "hr.manage"
        ]
      },
      "patch": {
        "operationId": "TripsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTripDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateTripResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Update the caller’s draft trip",
        "description": "Draft trips only. Changing the dates re-materialises the travel days; changing the project carries the new value onto the expense lines that were still inheriting it, and the response reports how many moved and how many a locked batch held back.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      },
      "delete": {
        "operationId": "TripsController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Delete the caller’s draft trip",
        "description": "Draft trips only. Its travel days and inherited lines go with it.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/trips/{id}/days/{dayId}": {
      "patch": {
        "operationId": "TripsController_updateDay",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dayId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTripDayDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Adjust one travel day of the caller’s draft trip",
        "description": "Per-day inputs the automatic resolution cannot know: free meals received, an overnight stay, or a country pin that overrides the route. Draft trips only.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/trips/{id}/submit": {
      "post": {
        "operationId": "TripsController_submit",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Submit the caller’s trip for approval",
        "description": "Hands the whole claim — trip, travel days and its expense lines — to the approver and freezes the amounts. This is the step that turns a draft into a pending decision.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/trips/{id}/reopen": {
      "post": {
        "operationId": "TripsController_reopen",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Trips"
        ],
        "summary": "Reopen the caller’s submitted trip",
        "description": "Takes a submitted trip back to draft. An approved trip is not reopenable.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/trips/{id}/approve": {
      "post": {
        "operationId": "TripsController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve a travel claim",
        "description": "The decision half of the `trip` rows in the approval queue. Requires supervisor authority over the traveller.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/trips/{id}/return": {
      "post": {
        "operationId": "TripsController_returnToDraft",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnTripDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Return a travel claim to the traveller",
        "description": "The other decision half of the `trip` rows in the approval queue: the claim reopens as the traveller’s draft and the reason routes back to them. Requires supervisor authority over the traveller.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/projects": {
      "get": {
        "operationId": "ProjectsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "id",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List projects",
        "description": "The project register as a cursor-paginated list, ordered by project code. Filter with `customerId`, `id` or `q` (code/name typeahead). Pass `updatedSince` for an incremental sweep: the page then carries only projects changed at or after that instant, ordered by `updatedAt` — resume from the largest `updatedAt` you have stored and de-duplicate by `id`. Deleted projects never appear here; read them from `GET /v1/integration-events`.\n\n**Capability:** `projects.read` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "projects.read"
        ]
      },
      "post": {
        "operationId": "ProjectsController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProjectDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Create a project",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/report": {
      "get": {
        "operationId": "ProjectsController_projectReport",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tesCost",
            "required": false,
            "in": "query",
            "description": "Reprice the period through the payroll interpretation into `tesCost` (default true). Pass `false` when only the report meta is wanted — it is the expensive part of this call.",
            "schema": {
              "enum": [
                "true",
                "false"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectReportResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Get the margin report of a project for a period",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}": {
      "patch": {
        "operationId": "ProjectsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProjectDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Update a project",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/status-updates": {
      "get": {
        "operationId": "ProjectsController_statusUpdates",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectStatusUpdateListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List the status updates of a project",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "ProjectsController_createStatusUpdate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProjectStatusUpdateDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectStatusUpdateViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Post a status update on a project",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/installments": {
      "get": {
        "operationId": "ProjectsController_listInstallments",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectInstallmentListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List the billing installments of a project",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/purchases": {
      "get": {
        "operationId": "ProjectsController_listPurchases",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectPurchaseListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List the purchases of a project",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/activity": {
      "get": {
        "operationId": "ProjectsController_activity",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectActivityResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Get the activity of a project for a period",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/phases": {
      "get": {
        "operationId": "ProjectsController_phases",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectPhaseListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List the phases of a project",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/export-batches": {
      "post": {
        "operationId": "ExportController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExportBatchDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportBatchViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payroll exports"
        ],
        "summary": "Create a payroll export batch",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      },
      "get": {
        "operationId": "ExportController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportBatchListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payroll exports"
        ],
        "summary": "List payroll export batches",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/export-batches/preflight": {
      "get": {
        "operationId": "ExportController_preflight",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "groupId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportPreflightResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payroll exports"
        ],
        "summary": "Check payroll export readiness for a period",
        "description": "Read-only pre-export verdict for `from`–`to`: exportable and still-unapproved day counts, carry-over from earlier periods, per-target pay-code coverage, non-blocking warnings and the calculation exceptions that block locking. Creates nothing. A single verdict object for one period, so it is not paginated.\n\n**Capability:** `payroll.run` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "payroll.run"
        ]
      }
    },
    "/v1/export-batches/{id}/components": {
      "get": {
        "operationId": "ExportController_components",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "targetId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalculationRunResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payroll exports"
        ],
        "summary": "Get the locked pay components of a batch",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/export-batches/{id}/cancel": {
      "post": {
        "operationId": "ExportController_cancel",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancelExportBatchDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelExportBatchResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payroll exports"
        ],
        "summary": "Cancel a payroll export batch",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/team/members/{membershipId}/work-days": {
      "get": {
        "operationId": "TeamDaysController_getRange",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayRangeResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "List work days for a member",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    },
    "/v1/team/members/{membershipId}/work-days/details": {
      "get": {
        "operationId": "TeamDaysController_getDayDetails",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayDetailRangeResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Get a member’s work days with entries",
        "description": "The window form of GET /v1/team/members/{membershipId}/work-days/{date}: the SAME per-day content — entries, breaks, supplements, effective settings, the open correction request — for every day in [from, to], in one request. Days the member has no working-time model for are absent, exactly as the single-day route answers 404 for them. Beyond 31 days the request answers 422 range_too_long. Same authority as the single-day read; no on-behalf opt-in is required to READ.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/work-days/{date}": {
      "get": {
        "operationId": "TeamDaysController_getDay",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Get a member’s work day with entries",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    },
    "/v1/team/members/{membershipId}/work-days/{date}/entries": {
      "put": {
        "operationId": "TeamDaysController_setEntries",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetWorkEntriesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Replace a member’s work entries for a day",
        "description": "THE time-import route: writes one member’s day from an external system (a terminal, another time tracker, a migration). The request REPLACES the day’s entries in full, so re-sending the same body is idempotent — a retried import cannot double-write and needs no Idempotency-Key. Draft days only: a confirmed, approved or exported day answers 409 day_confirmed_locked and must go back to draft through reopen (confirmed) or correct (approved/exported) first — a record past the confirmation boundary is never edited in place. Requires the organisation’s “supervisor may act on behalf” setting and authority over the member.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/work-days/{date}/batch-entries": {
      "post": {
        "operationId": "TeamDaysController_batchEntries",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TeamBatchEntriesDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TeamBatchEntriesResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Write the same work day for several members",
        "description": "Batch form of PUT /v1/team/members/{membershipId}/work-days/{date}/entries: ONE day’s content — entries (with their stated breaks) or a full-day day type — written for up to 100 members at once, which is what a crew that worked the same Saturday needs. Each member is its own transaction with its own audit event, exactly as N separate calls would be; a member the caller may not act for (403 not_authorized / on_behalf_disabled) or whose day has left draft (409 day_confirmed_locked) is reported in `skipped` with that code instead of failing the batch. Beyond 100 members the request answers 422 batch_too_large. Because each member’s day is REPLACED in full, re-sending the same body is idempotent and needs no Idempotency-Key.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/work-days/{date}/day-type": {
      "put": {
        "operationId": "TeamDaysController_setDayType",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDayTypeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Set a member’s full-day day type",
        "description": "Marks the whole day as one day type (from GET /v1/day-types) instead of entries — the import path for “this day was a public holiday / a training day”. Full replacement of the day’s type, so re-sending it is idempotent. Draft days only (409 day_confirmed_locked otherwise).\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/work-days/{date}/confirm": {
      "post": {
        "operationId": "TeamDaysController_confirm",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfirmWorkDayDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfirmWorkDayResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Confirm a member’s work day on their behalf",
        "description": "Asserts the day as the member’s record: it crosses the confirmation boundary (draft → confirmed) and writes an append-only lifecycle event naming the acting key. Emits workday.confirmed. A day that is already confirmed answers 409 day_already_confirmed, so a retried call cannot confirm twice; the transition is guarded on the day’s status, which is why no Idempotency-Key is required (send one anyway to replay the original response instead of the 409).\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/work-days/confirm-range": {
      "post": {
        "operationId": "TeamDaysController_confirmRange",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RangeActionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RangeActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Confirm a member’s work days over a date range",
        "description": "Confirms every day in the range that can confirm; days that cannot (already confirmed, empty free day) are SKIPPED, never failed, and counted in skippedCount. Each day is its own transaction and emits its own workday.confirmed — N days produce N events, not one. Maximum window 31 days (422 range_too_long beyond it). A retry is safe: already-confirmed days simply skip, so the second call reports actedCount 0 — send an Idempotency-Key to replay the original counts instead.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/work-days/{date}/reopen": {
      "post": {
        "operationId": "TeamDaysController_reopen",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Reopen a member’s confirmed work day",
        "description": "Takes a confirmed (not yet approved) day back to draft so its entries can be written again — the way an import corrects a day it already confirmed. Records an append-only lifecycle event and emits workday.returned. Allowed only while the day is confirmed: a draft answers 409 day_already_editable and an approved day 409 day_already_approved (use correct instead).\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/work-days/reopen-range": {
      "post": {
        "operationId": "TeamDaysController_reopenRange",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RangeActionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RangeActionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "Reopen a member’s confirmed work days over a date range",
        "description": "Range form of reopen: every still-confirmed day in the window goes back to draft, one transaction and one workday.returned event per day. Days that cannot reopen (already draft, approved, exported, or no row) are skipped, never failed. Maximum window 31 days (422 range_too_long beyond it).\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/work-days": {
      "get": {
        "operationId": "WorkDayRegisterController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "membershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "confirmed",
                "approved",
                "exported"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayRegisterPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Work days"
        ],
        "summary": "List work days across the organisation",
        "description": "The stored work-day rows for an inclusive `from`–`to` window (max 366 days), cursor-paginated. Scoped like the team grid: admin and payroll read the whole organisation, a manager their own reports. Add `updatedSince` to read only what changed — the list then orders by `(updatedAt asc, id asc)` and the window still applies. Deletions never appear in a list; read them from `GET /v1/integration-events`. For the calculated day (target, applied credit, balance terms) read the per-member day detail.\n\n**Capability:** `worktime.supervise` or `payroll.run` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise",
          "payroll.run"
        ]
      }
    },
    "/v1/customers/{id}/contacts": {
      "get": {
        "operationId": "ContactsController_list",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "List the contacts of a customer",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "ContactsController_create",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Create a contact for a customer",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/contacts/{id}": {
      "patch": {
        "operationId": "CrmContactsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Update a contact",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/customers/{id}/crm-360": {
      "get": {
        "operationId": "Customer360Controller_get360",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer360ViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Get the 360-degree view of a customer",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/leads": {
      "get": {
        "operationId": "LeadsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "new",
                "working",
                "converted",
                "discarded"
              ]
            }
          },
          {
            "name": "ownerMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "source",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "manual",
                "intake",
                "import",
                "website",
                "referral",
                "other"
              ]
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "List leads",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "LeadsController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLeadDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Create a lead",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/leads/{id}": {
      "patch": {
        "operationId": "LeadsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLeadDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Update a lead",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/leads/{id}/convert": {
      "post": {
        "operationId": "LeadsController_convert",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConvertLeadDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConvertLeadResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Convert a lead into a customer and deal",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/pipelines": {
      "get": {
        "operationId": "PipelinesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PipelineListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "List pipelines with their stages",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/deals": {
      "get": {
        "operationId": "DealsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "pipelineId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "stageId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "won",
                "lost"
              ]
            }
          },
          {
            "name": "ownerMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "tagId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "stale",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "valueCents",
                "expectedCloseDate",
                "nextActivityAt"
              ]
            }
          },
          {
            "name": "direction",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "List deals",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "DealsController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDealDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Create a deal",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/deals/{id}": {
      "get": {
        "operationId": "DealsController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Get a deal",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      },
      "patch": {
        "operationId": "DealsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDealDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Update a deal",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/deals/{id}/stage": {
      "post": {
        "operationId": "DealsController_moveStage",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MoveDealStageDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Move a deal to another pipeline stage",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/deals/{id}/win": {
      "post": {
        "operationId": "DealsController_win",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WinDealDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Mark a deal as won",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/deals/{id}/lose": {
      "post": {
        "operationId": "DealsController_lose",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoseDealDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Mark a deal as lost",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/pipelines/{id}/board": {
      "get": {
        "operationId": "BoardController_board",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BoardViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Get the deal board of a pipeline",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/activities": {
      "get": {
        "operationId": "ActivitiesController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "dealId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "leadId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "ownerMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "call",
                "meeting",
                "email",
                "note",
                "task"
              ]
            }
          },
          {
            "name": "state",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "done"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "List CRM activities",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "ActivitiesController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateActivityDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Create an activity",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/activities/agenda": {
      "get": {
        "operationId": "ActivitiesController_agenda",
        "parameters": [
          {
            "name": "ownerMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "onDate",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityAgendaResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Get the sales activity agenda",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/crm/activities/{id}/done": {
      "post": {
        "operationId": "ActivitiesController_toggleDone",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ToggleActivityDoneDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "CRM"
        ],
        "summary": "Mark an activity done or reopen it",
        "x-kelomo-capabilities": [
          "crm.use"
        ],
        "description": "**Capability:** `crm.use` — an API key must carry this in its scope."
      }
    },
    "/v1/api-keys": {
      "get": {
        "operationId": "ApiKeysController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "API keys"
        ],
        "summary": "List every API key in the organisation (human session required)",
        "description": "Includes the owner member each key executes as, so an offboarding can see what a leaver carries.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/api-keys/service": {
      "post": {
        "operationId": "ApiKeysController_createService",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateServiceApiKeyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateApiKeyResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "API keys"
        ],
        "summary": "Create a service API key with a named owner (human session required)",
        "description": "A service key belongs to the organisation and executes with the named owner member’s authority. The owner and the capabilities are both required, the capabilities must fit the owner’s effective set, and the key value is returned once, in this response only.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/api-keys/{id}/reassign": {
      "post": {
        "operationId": "ApiKeysController_reassign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReassignApiKeyDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "API keys"
        ],
        "summary": "Reassign a service API key to another owner (human session required)",
        "description": "The token and its scopes are unchanged; only the executing identity moves. The scopes are re-validated against the new owner’s effective set.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/api-keys/{id}": {
      "delete": {
        "operationId": "ApiKeysController_revoke",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "API keys"
        ],
        "summary": "Revoke any API key in the organisation (human session required)",
        "x-kelomo-capabilities": [
          "org.admin"
        ],
        "description": "**Capability:** `org.admin` — an API key must carry this in its scope."
      }
    },
    "/v1/me/api-keys": {
      "get": {
        "operationId": "MeApiKeysController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s own API keys (human session required)",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      },
      "post": {
        "operationId": "MeApiKeysController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateApiKeyResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Create an API key for the caller (human session required)",
        "description": "The key acts as the caller: its capabilities must fit the caller’s own effective set. The key value is returned once, in this response only, and a key cannot manage keys.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/api-keys/{id}/rotate": {
      "post": {
        "operationId": "MeApiKeysController_rotate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateApiKeyResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Rotate the caller’s own API key (human session required)",
        "description": "The previous token keeps authenticating for 24 hours.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/api-keys/{id}": {
      "delete": {
        "operationId": "MeApiKeysController_revoke",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Revoke the caller’s own API key (human session required)",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/access": {
      "get": {
        "operationId": "AccessController_describe",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessContextDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Describe the credential this request was made with",
        "description": "The member the call acts as, the capabilities it can actually exercise (the member’s effective set intersected with the key’s scope), the key’s own declaration, and the rate limits in force. Compare `capabilities` with an operation’s `x-kelomo-capabilities` when a call is refused with `insufficient_role`.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/oauth-grants": {
      "get": {
        "operationId": "OAuthGrantsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthGrantListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "API keys"
        ],
        "summary": "List every connected app in the organisation (human session required)",
        "description": "One row per app-and-member connection, with the capabilities the member consented to and when the app last called. Revoked connections are omitted.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/oauth-grants/{id}": {
      "delete": {
        "operationId": "OAuthGrantsController_revoke",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthGrantOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "API keys"
        ],
        "summary": "Disconnect any app in the organisation (human session required)",
        "description": "Ends the connection immediately: the refresh token family dies and the next call with an existing access token is refused.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/me/oauth-grants": {
      "get": {
        "operationId": "MeOAuthGrantsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthGrantListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s own connected apps (human session required)",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/oauth-grants/{id}": {
      "delete": {
        "operationId": "MeOAuthGrantsController_revoke",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthGrantOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Disconnect one of the caller’s own apps (human session required)",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/shift-plans": {
      "get": {
        "operationId": "ShiftPlansController_plan",
        "parameters": [
          {
            "name": "planningUnitId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftPlanResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Shifts"
        ],
        "summary": "Get the shift plan of a planning unit for a date range",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ],
        "description": "**Capability:** `scheduling.plan` — an API key must carry this in its scope."
      }
    },
    "/v1/shift-plans/{planningUnitId}/uncovered": {
      "get": {
        "operationId": "ShiftPlansController_uncovered",
        "parameters": [
          {
            "name": "planningUnitId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UncoveredShiftListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Shifts"
        ],
        "summary": "List published shifts in a unit whose assignee is absent",
        "description": "The coverage gaps of one planning unit over `from`–`to`: published shifts whose assignee is absent that day and therefore need cover. Read-only.\n\n**Capability:** `scheduling.plan` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ]
      }
    },
    "/v1/shift-plans/publish-events": {
      "get": {
        "operationId": "ShiftPlansController_publishEvents",
        "parameters": [
          {
            "name": "planningUnitId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishEventPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Shifts"
        ],
        "summary": "List publish events of a planning unit",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ],
        "description": "**Capability:** `scheduling.plan` — an API key must carry this in its scope."
      }
    },
    "/v1/planning-units": {
      "get": {
        "operationId": "PlanningUnitsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanningUnitListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List planning units",
        "x-kelomo-capabilities": [
          "scheduling.plan",
          "members.manage"
        ],
        "description": "**Capability:** `scheduling.plan` or `members.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/me/shifts": {
      "get": {
        "operationId": "MyShiftsController_myShifts",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MyShiftsResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s published shifts for a date range",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/open-shifts": {
      "get": {
        "operationId": "MyShiftsController_openShifts",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenShiftPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List open shifts offered to the caller, with own claim status",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/open-shifts/{id}/claim": {
      "post": {
        "operationId": "MyShiftsController_claim",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClaimOpenShiftDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchedulingOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Claim an open shift offered to the caller",
        "description": "Registers the caller’s claim on an open shift from `GET /v1/me/open-shifts`. The claim is a request, not an assignment: a planner decides between the claims, and the shift lands on the roster only when one is approved. An optional message opens a thread with the claim.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      },
      "delete": {
        "operationId": "MyShiftsController_withdrawClaim",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchedulingOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Withdraw the caller’s claim on an open shift",
        "description": "Removes the caller’s pending claim on an open shift. Only an undecided claim can be withdrawn.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/unit-roster": {
      "get": {
        "operationId": "MyShiftsController_unitRoster",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnitRosterResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the published roster of the caller’s own unit",
        "description": "The published shifts of the caller’s planning unit over `from`–`to` (the direct-swap picker source), plus the caller’s units for the unit selector. A range-bounded read, so it is not paginated. Requires the tenant (or the caller’s unit) to have autonomous scheduling enabled.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/open-shifts": {
      "get": {
        "operationId": "OpenShiftsController_list",
        "parameters": [
          {
            "name": "planningUnitId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenShiftPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Shifts"
        ],
        "summary": "List open shifts of a planning unit, with pending claims",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ],
        "description": "**Capability:** `scheduling.plan` — an API key must carry this in its scope."
      }
    },
    "/v1/open-shifts/{id}/approve": {
      "post": {
        "operationId": "OpenShiftsController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveClaimDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchedulingOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve a member’s claim on an open shift",
        "description": "The decision half of the `open_shift_claim` rows in the approval queue: `membershipId` picks WHICH claimant gets the shift when several have claimed it.\n\n**Capability:** `scheduling.plan` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ]
      }
    },
    "/v1/open-shifts/{id}/reject": {
      "post": {
        "operationId": "OpenShiftsController_reject",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveClaimDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchedulingOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Reject a member’s claim on an open shift",
        "description": "The other decision half of the `open_shift_claim` rows in the approval queue: `membershipId` picks WHICH claim is rejected, and the reason routes back to that claimant. The shift stays open for the remaining claims.\n\n**Capability:** `scheduling.plan` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ]
      }
    },
    "/v1/shift-swaps": {
      "get": {
        "operationId": "ShiftSwapsController_list",
        "parameters": [
          {
            "name": "planningUnitId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftSwapPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Shifts"
        ],
        "summary": "List shift swap requests of a planning unit",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ],
        "description": "**Capability:** `scheduling.plan` — an API key must carry this in its scope."
      }
    },
    "/v1/shift-swaps/{id}/approve": {
      "post": {
        "operationId": "ShiftSwapsController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchedulingOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve a shift swap between two members",
        "description": "The decision half of the `swap` rows in the approval queue: both members’ published shifts change hands when the swap is approved.\n\n**Capability:** `scheduling.plan` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ]
      }
    },
    "/v1/shift-swaps/{id}/reject": {
      "post": {
        "operationId": "ShiftSwapsController_reject",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RejectSwapDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SchedulingOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Reject a shift swap between two members",
        "description": "The other decision half of the `swap` rows in the approval queue: both members keep their published shifts and the reason routes back to the requester.\n\n**Capability:** `scheduling.plan` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "scheduling.plan"
        ]
      }
    },
    "/v1/day-types": {
      "get": {
        "operationId": "DayTypesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DayTypeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List day types",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/entry-types": {
      "get": {
        "operationId": "EntryTypesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryTypeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List work entry types",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/break-types": {
      "get": {
        "operationId": "BreakTypesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BreakTypeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List break types",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/shift-types": {
      "get": {
        "operationId": "ShiftTypesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftTypeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List shift types",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/balance-transactions": {
      "get": {
        "operationId": "BalancesController_list",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceTransactionListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Balances"
        ],
        "summary": "List a member’s balance transactions",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/me/balance-transactions": {
      "get": {
        "operationId": "MeBalanceTransactionsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "accountTypeId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceTransactionListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s balance transactions",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/balance-account-types": {
      "get": {
        "operationId": "BalanceAccountTypesController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceAccountTypeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Balances"
        ],
        "summary": "List balance account types",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/dimensions": {
      "get": {
        "operationId": "DimensionsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Catalogs"
        ],
        "summary": "List tracking dimensions",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/customers": {
      "get": {
        "operationId": "CustomersController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "minLength": 1,
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "ownerMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "tagId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "includeInactive",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Customers"
        ],
        "summary": "List customers",
        "description": "Buyer billing identifiers are masked for manager-tier callers exactly as in the UI.\n\n**Capability:** `crm.use` or `payroll.run` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "crm.use",
          "payroll.run"
        ]
      },
      "post": {
        "operationId": "CustomersController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Customers"
        ],
        "summary": "Create a customer",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/customers/{id}": {
      "get": {
        "operationId": "CustomersController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGetResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Customers"
        ],
        "summary": "Get a customer",
        "description": "Buyer billing identifiers are masked for manager-tier callers exactly as in the UI.\n\n**Capability:** `crm.use` or `payroll.run` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "crm.use",
          "payroll.run"
        ]
      },
      "patch": {
        "operationId": "CustomersController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Customers"
        ],
        "summary": "Update a customer",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/memberships/{id}/employment": {
      "get": {
        "operationId": "EmploymentController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmploymentResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Get the member’s employment terms",
        "description": "The terms record behind the PUT below — job title, employment and pay type, fixed-term grounds and end date, probation, contract hours, place of work, employer, payroll number and insurers. Published because the PUT is a full replace: read this, change what you mean to change, send the whole object back. Carries no monetary amounts and none of the sensitive personal tier (identity number, bank account, home address are not reachable over the API at all). Requires the HR add-on module; a supervisor reads it only when the organisation allows it (`403 manager_terms_read_disabled`).\n\n**Capability:** `reports.team` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "reports.team"
        ]
      },
      "put": {
        "operationId": "EmploymentController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEmploymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmploymentOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Replace the member’s employment terms",
        "description": "Full REPLACE, not a patch: every omitted optional field is CLEARED, so read `GET /v1/memberships/{id}/employment` first and send the whole object back. `employmentType` and `payType` are required. Fixed-term employment requires written grounds (`422 fixed_term_requires_grounds`, Employment Contracts Act 1:3). This is the terms record; the employment WINDOW (start/end dates) is on `PATCH /v1/memberships/{id}`, and DATED terms changes — the version history payroll calculates historical weeks from — are deliberately not part of the public API. A PUT is a correction of the CURRENT terms: it keeps the open version in step and never rewrites a closed one. Requires the HR add-on module. Fires `member.updated`.\n\n**Capability:** `hr.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "hr.manage"
        ]
      }
    },
    "/v1/memberships/{id}/payroll-identity": {
      "get": {
        "operationId": "PayrollIdentityController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayrollIdentityViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Read a member’s payroll identifier",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      },
      "put": {
        "operationId": "PayrollIdentityController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePayrollIdentityDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmploymentOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Set a member’s payroll identifier",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/memberships/{id}/termination": {
      "post": {
        "operationId": "EmploymentLifecycleController_terminate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TerminateEmploymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TerminationResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Record a termination",
        "description": "Records the end of the employment: writes the member’s `employmentEndDate`, the coded `reasonCode`, the `noticeDate` that anchors the notice period and an optional note, and starts an offboarding checklist run when `startOffboarding` is true. It does NOT deactivate the member — the end-date sweep does that on the day itself, or call `POST /v1/memberships/{id}/deactivate` explicitly. Repeating the call overwrites the record rather than adding a second one. `422 termination_end_before_start`. Requires the HR add-on module. Fires `employment.terminated` (identifiers and end date only — the reason and the note never ride the event).\n\n**Capability:** `hr.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "hr.manage"
        ]
      },
      "delete": {
        "operationId": "EmploymentLifecycleController_cancel",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TerminationResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Cancel a recorded termination",
        "description": "Clears the end date and the termination fields. Deliberately narrow: it does not cancel an offboarding checklist run and does not reactivate a member the end-date sweep already deactivated — both are separate, separately-audited operations (`POST /v1/memberships/{id}/reactivate`). `404 termination_not_found` when nothing is recorded. Requires the HR add-on module. Fires `member.updated`.\n\n**Capability:** `hr.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "hr.manage"
        ]
      }
    },
    "/v1/me/absence/policies": {
      "get": {
        "operationId": "AbsenceController_listPolicies",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePolicyListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List absence policies the caller can request",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/absence-periods": {
      "get": {
        "operationId": "AbsenceController_listMine",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s absence periods for a date range",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      },
      "post": {
        "operationId": "AbsenceController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Create a draft absence request for the caller",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/absence-periods/preview": {
      "post": {
        "operationId": "AbsenceController_preview",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodPreviewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Preview an absence request’s day resolution and balance impact",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/absence-periods/{id}/submit": {
      "post": {
        "operationId": "AbsenceController_submit",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Submit the caller’s absence request for approval",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/me/absence-periods/{id}/withdraw": {
      "post": {
        "operationId": "AbsenceController_withdraw",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Withdraw the caller’s submitted absence request",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/absence-periods/{id}": {
      "get": {
        "operationId": "AbsenceController_detail",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Absences"
        ],
        "summary": "Get an absence period’s detail",
        "description": "Absence types are masked by sensitivity exactly as in the UI.\n\n**Capability:** `worktime.supervise` or `hr.manage` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise",
          "hr.manage"
        ]
      }
    },
    "/v1/absence-periods/{id}/cancel": {
      "post": {
        "operationId": "AbsenceController_cancel",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Absences"
        ],
        "summary": "Cancel an approved absence period",
        "description": "Reverses the period’s balance consumption. Refused with 409 `absence_cancel_after_confirmed_day` once a materialised day has been confirmed — leave actually taken is an append-only record; postpone the untaken tail instead. Pass `expectedUpdatedAt` from the period detail to detect a concurrent decision.\n\n**Capability:** none for the caller's own record — its authorisation is row-level. Reaching ANOTHER member's record with an API key additionally requires `worktime.supervise` or `hr.manage` in the key's scope.",
        "x-kelomo-capabilities": [],
        "x-kelomo-capabilities-beyond-self": [
          "worktime.supervise",
          "hr.manage"
        ]
      }
    },
    "/v1/team/absence": {
      "get": {
        "operationId": "AbsenceController_team",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TeamAbsenceResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Absences"
        ],
        "summary": "List team absences for a date range",
        "description": "Absence types are masked by sensitivity exactly as in the UI.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/absence-periods/{id}/approve": {
      "post": {
        "operationId": "AbsenceController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve a submitted absence period",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    },
    "/v1/absence-periods/{id}/reject": {
      "post": {
        "operationId": "AbsenceController_reject",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RejectAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Reject a submitted absence period",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    },
    "/v1/team/absence/preview": {
      "post": {
        "operationId": "AbsenceController_teamPreview",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodPreviewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Absences"
        ],
        "summary": "Preview an employer-assigned absence for a member",
        "description": "Resolves the period day by day and reports the balance it would consume plus any conflicts (confirmed days, overlapping absences, shift coverage) — without writing anything. Run this before assigning, so an import can refuse a whole file instead of half-placing it.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/absence/plan": {
      "post": {
        "operationId": "AbsenceController_plan",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanAbsencePeriodDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AbsencePeriodDetailDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Absences"
        ],
        "summary": "Assign an absence to a member",
        "description": "Creates the period already granted, the way an employer places leave (shutdown, layoff) or an HR system of record pushes an approved absence. Only policies marked employer-assignable are accepted; the balance is consumed and `absence.decided` is emitted. Preview first to see the consumption and conflicts. Retrying a placement that already exists is refused with 422 `absence_period_overlap` rather than booked twice, so a timed-out request is safe to repeat.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/me/leave-balance": {
      "get": {
        "operationId": "LeaveEntitlementController_myBalance",
        "parameters": [
          {
            "name": "asOf",
            "required": false,
            "in": "query",
            "description": "ISO date to project to (default: today)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveBalanceResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Get the caller’s leave balance, optionally projected to a date",
        "x-kelomo-capabilities": [],
        "description": "**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it."
      }
    },
    "/v1/leave-save-proposals/{id}/approve": {
      "post": {
        "operationId": "LeaveEntitlementController_approveSaveProposal",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveLeaveSaveProposalDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveSaveProposalOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve a saved-leave proposal",
        "description": "The decision half of the `leave_save` rows in the approval queue; executes the annual-holidays-act § 27 ledger transfer. `expectedUpdatedAt` is the optimistic-concurrency stamp read from the queue row.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/leave-save-proposals/{id}/decline": {
      "post": {
        "operationId": "LeaveEntitlementController_declineSaveProposal",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeclineLeaveSaveProposalDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveSaveProposalOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Decline a saved-leave proposal",
        "description": "The other decision half of the `leave_save` rows in the approval queue: no ledger transfer happens and the reason routes back to the proposer. `expectedUpdatedAt` is the optimistic-concurrency stamp read from the queue row.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/team/members/{membershipId}/leave-balance": {
      "get": {
        "operationId": "LeaveEntitlementController_memberBalance",
        "parameters": [
          {
            "name": "membershipId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "asOf",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveBalanceResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Absences"
        ],
        "summary": "Get a report’s projected leave balance",
        "description": "Scoped to the caller’s reports.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/memberships": {
      "get": {
        "operationId": "MembershipsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "role",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "employee",
                "manager",
                "admin",
                "payroll",
                "hr"
              ]
            }
          },
          {
            "name": "unitId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "employerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "future",
                "ended"
              ]
            }
          },
          {
            "name": "incompleteOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "includeInactive",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "leadsOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "excludePayroll",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "attention",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "needsAttention",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "List members of the organisation",
        "description": "Scoped to the caller’s authority: a supervisor sees only their own reports.\n\n**Capability:** `members.manage` or `worktime.supervise` or `payroll.run` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "members.manage",
          "worktime.supervise",
          "payroll.run"
        ]
      },
      "post": {
        "operationId": "MembershipsController_create",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMembershipDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateMembershipResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Create a member",
        "description": "Required: `displayName` and `role`. `email` is optional — omit it for a device-only punch-clock worker, and the server mints a synthetic, never-deliverable address and sends no invite (give a `phone` so SMS can still reach them). Every optional id (`managerMembershipId`, `worktimeModelId`, `leaveGroupId`) is readable from the public surface, so nothing here needs an internal endpoint. A new passwordless member is created AND invited in one call: `member.created` and `member.invited` both fire, and the response carries the one-time activation URL. Called with an API key the `Idempotency-Key` header is REQUIRED — a retried create then replays the original 201 instead of answering `409 already_member` with no id. Re-creating an address that is already a member of this organisation is `409 already_member`.\n\n**Capability:** `members.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "members.manage"
        ]
      }
    },
    "/v1/memberships/{id}": {
      "get": {
        "operationId": "MembershipsController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Get a member’s record",
        "x-kelomo-capabilities": [
          "members.manage",
          "worktime.supervise",
          "payroll.run"
        ],
        "description": "**Capability:** `members.manage` or `worktime.supervise` or `payroll.run` — an API key must carry one of these in its scope."
      },
      "patch": {
        "operationId": "MembershipsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMembershipDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Update a member",
        "description": "Partial update — only the fields present in the body change. The EMPLOYMENT WINDOW lives here (`employmentStartDate` / `employmentEndDate`, both nullable), alongside role, supervisor, worktime model, primary planning unit and leave group. A `planningUnitId` change is effective-dated from today and never rewrites which unit the person belonged to in the past. Refused for a supervisor loop (`422 manager_cannot_be_self`, `422 manager_cycle`) and for demoting yourself (`422 cannot_change_own_role`); a role change ends the member’s live sessions. The privilege fields (`hrScopeUnitIds`, `hrRecorder`, `crmSeat`, `canPlanAllUnits`) are admin-only and refused for anyone else. Fires `member.updated`.\n\n**Capability:** `members.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "members.manage"
        ]
      }
    },
    "/v1/memberships/bulk": {
      "post": {
        "operationId": "MembershipsController_bulk",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateMembershipsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkCreateMembershipsResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Create members in bulk",
        "description": "The migration on-ramp: 1–500 rows per request (`rows`), each created independently so one bad row never fails the batch. Always answers 200 with a per-row outcome — `invited`, `created`, `skipped` (already a member) or `error` with a machine-readable `code` (`manager_not_found`, `planning_unit_not_found`, `worktime_model_not_found`, `employer_not_found`). A row may name its supervisor by e-mail and its unit / worktime model / employer by name or registry code, resolved server-side against this organisation AND the other rows of the same request, so a payroll export can be posted without looking any ids up first. Re-posting the same file is safe: existing members are skipped, never duplicated, so no `Idempotency-Key` is needed. Fires `member.created` (and `member.invited`) per created row.\n\n**Capability:** `members.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "members.manage"
        ]
      }
    },
    "/v1/memberships/{id}/invite": {
      "post": {
        "operationId": "MembershipsController_invite",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteMemberDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipInviteResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Send or resend the activation invite",
        "description": "Mints a NEW single-use activation link — the previous one stops working — and e-mails it in `locale` (default: the member’s own preferred language). Not needed after `POST /v1/memberships`, which already invites; this is the \"the mail never arrived\" and \"the link expired\" path. Refused with `422 invitation_accepted` when the member already has a password and `422 membership_deactivated` for an offboarded member. Fires `member.invited` on every send: each send is a real issuance that supersedes the previous link.\n\n**Capability:** `members.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "members.manage"
        ]
      }
    },
    "/v1/memberships/{id}/units": {
      "post": {
        "operationId": "MembershipsController_addUnit",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddMembershipUnitDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Assign the member to a planning unit",
        "description": "Multi-unit membership: adds ONE MORE open unit assignment (effective today) so the person can be rostered there; the member’s first unit also becomes their primary one. `planningUnitId` comes from `GET /v1/planning-units`; an unknown id is `404 planning_unit_not_found`. Needs the `org.admin` scope — for the ordinary \"which unit does this person belong to\" case use `planningUnitId` on `PATCH /v1/memberships/{id}`, which needs only `members.manage`. Fires `member.updated`.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/memberships/{id}/units/{unitId}": {
      "delete": {
        "operationId": "MembershipsController_removeUnit",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unitId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Remove a planning unit from the member",
        "description": "Closes the assignment as of today; the past is kept, so which unit’s shifts applied last month never changes. If the removed unit was the primary one, another open assignment takes its place — or none, when it was the last. Needs the `org.admin` scope. Fires `member.updated`.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/memberships/{id}/deactivate": {
      "post": {
        "operationId": "MembershipsController_deactivate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeactivateMembershipResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Deactivate a member",
        "description": "Offboarding: all bookkeeping history is kept, sign-in is blocked and the member’s live sessions end immediately. This operation NEVER fails on account of API keys — offboarding must always be possible — so the response instead lists in `orphanedServiceKeys` the SERVICE keys the member owned. Those keys execute with their owner’s authority and stop authenticating (`401 api_key_owner_inactive`) the moment the owner does, so reassign them or the integrations behind them go dark. Personal keys are deliberately not listed: dying with their owner is what a personal key is for. Idempotent — a second call is a no-op with an empty list and emits nothing. Fires `member.deactivated` on a real change. `422 cannot_deactivate_self`.\n\n**Capability:** `members.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "members.manage"
        ]
      }
    },
    "/v1/memberships/{id}/reactivate": {
      "post": {
        "operationId": "MembershipsController_reactivate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MembershipOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Members"
        ],
        "summary": "Reactivate a member",
        "description": "Brings a deactivated member back into the active roster (a rehire, or an offboarding that turned out to be wrong). Service keys the member owns start authenticating again by themselves — the owner’s status is checked per request, not frozen at deactivation. Idempotent; fires `member.updated` on a real change.\n\n**Capability:** `members.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "members.manage"
        ]
      }
    },
    "/v1/training-requests/{id}/approve": {
      "post": {
        "operationId": "TrainingRequestsController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveTrainingRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrainingRequestOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve a training request",
        "description": "The decision half of the `training` rows in the approval queue. `expectedUpdatedAt` is the optimistic-concurrency stamp read from the queue row.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/training-requests/{id}/decline": {
      "post": {
        "operationId": "TrainingRequestsController_decline",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeclineTrainingRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrainingRequestOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Decline a training request",
        "description": "The other decision half of the `training` rows in the approval queue: the reason routes back to the requester. `expectedUpdatedAt` is the optimistic-concurrency stamp read from the queue row.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/projects/portfolio/attention": {
      "get": {
        "operationId": "ProjectOverviewController_portfolioAttention",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectPortfolioAttentionResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Get the portfolio attention roll-up",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/roster": {
      "get": {
        "operationId": "ProjectOverviewController_roster",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "active",
                "on_hold",
                "closed"
              ]
            }
          },
          {
            "name": "health",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "on_track",
                "at_risk",
                "over_budget",
                "no_data"
              ]
            }
          },
          {
            "name": "situation",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "on_track",
                "at_risk",
                "off_track",
                "none"
              ]
            }
          },
          {
            "name": "mine",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "unbilled",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hours",
                "health",
                "margin",
                "budget",
                "name",
                "deadline"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectRosterResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List projects",
        "description": "Paginated, server-filtered and sorted portfolio roster; each row carries the project state and money figures.\n\n**Capability:** `projects.read` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "projects.read"
        ]
      }
    },
    "/v1/projects/{id}/overview": {
      "get": {
        "operationId": "ProjectOverviewController_overview",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectOverviewResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Get the overview aggregate of a project",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/tasks": {
      "get": {
        "operationId": "ProjectTasksController_board",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "statusId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "assigneeMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "phaseId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "milestoneId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "priority",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "low",
                "normal",
                "high",
                "urgent"
              ]
            }
          },
          {
            "name": "tagId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "includeClosed",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "fieldId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "fieldValue",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskBoardResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Tasks"
        ],
        "summary": "List the tasks of a project",
        "description": "The whole board: columns with card windows, dependencies and milestones. Page a single column with the tasks/page operation.\n\n**Capability:** `projects.read` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "projects.read"
        ]
      },
      "post": {
        "operationId": "ProjectTasksController_create",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTaskDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Tasks"
        ],
        "summary": "Create a task in a project",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/tasks/page": {
      "get": {
        "operationId": "ProjectTasksController_taskPage",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "statusId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "assigneeMembershipId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "phaseId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "milestoneId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "priority",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "low",
                "normal",
                "high",
                "urgent"
              ]
            }
          },
          {
            "name": "tagId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "includeClosed",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "fieldId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "fieldValue",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Tasks"
        ],
        "summary": "Page the tasks of a project",
        "description": "Cursor-paginated tasks in one of three lenses: one board column (statusId), the archive (archived=true) or everything changed since an instant (updatedSince — the incremental-sync read, which spans archived tasks too). Exactly one lens must be selected.\n\n**Capability:** `projects.read` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "projects.read"
        ]
      }
    },
    "/v1/projects/{id}/statuses": {
      "get": {
        "operationId": "ProjectTasksController_statuses",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskStatusListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Tasks"
        ],
        "summary": "List the task statuses of a project board",
        "description": "The closed status catalogue of one project’s task board. `PATCH /v1/me/tasks/{id}/status` takes a `statusId` from this list; `category` tells which statuses mean todo / in progress / done / cancelled.\n\n**Capability:** `projects.read` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "projects.read"
        ]
      }
    },
    "/v1/tasks/{id}": {
      "get": {
        "operationId": "TasksController_detail",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Tasks"
        ],
        "summary": "Get a task",
        "x-kelomo-capabilities": [
          "projects.read",
          "projects.manage"
        ],
        "description": "**Capability:** `projects.read` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/me/tasks": {
      "get": {
        "operationId": "MeTasksController_myTasks",
        "parameters": [
          {
            "name": "includeClosed",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeTasksResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the tasks assigned to the caller",
        "description": "The caller’s own task desk: tasks they are assignee, commenter or watcher on, plus the board status options (`boards[].statuses`) an assignee may move their own card between with `PATCH /v1/me/tasks/{id}/status`. Reachable with any key — the per-project board reads require `projects.read`, this one is the employee’s own surface.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/tasks/{id}/status": {
      "patch": {
        "operationId": "MeTasksController_changeStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MeTaskStatusChangeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Tasks"
        ],
        "summary": "Change the status of a task assigned to the caller",
        "description": "Moves the task to another board column. Only the assignee may move their own card here; 404 for tasks assigned to someone else.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/billing-export/candidates": {
      "get": {
        "operationId": "BillingExportController_candidates",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "granularity",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "targetId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingCandidatesResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Billing exports"
        ],
        "summary": "List billable candidates for a period",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/billing-export/batches": {
      "get": {
        "operationId": "BillingExportController_listBatches",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingBatchListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Billing exports"
        ],
        "summary": "List billing export batches",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      },
      "post": {
        "operationId": "BillingExportController_createBatch",
        "parameters": [
          {
            "name": "lang",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBillingBatchDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Billing exports"
        ],
        "summary": "Create a billing export batch",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/billing-export/batches/{id}/download": {
      "get": {
        "operationId": "BillingExportController_downloadBatch",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Billing exports"
        ],
        "summary": "Download a billing export batch file",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/billing-export/batches/{id}/deliver": {
      "post": {
        "operationId": "BillingExportController_deliver",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Billing exports"
        ],
        "summary": "Deliver a billing export batch to its target",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/billing-export/batches/{id}/deliveries": {
      "get": {
        "operationId": "BillingExportController_listDeliveries",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingDeliveryListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Billing exports"
        ],
        "summary": "List deliveries of a billing export batch",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices": {
      "get": {
        "operationId": "InvoicesController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "lane",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "approved",
                "issued",
                "sent",
                "overdue",
                "paid",
                "credited"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "issued"
              ]
            }
          },
          {
            "name": "documentType",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "credit_note",
                "reminder",
                "advance"
              ]
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "overdue",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "openOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicePageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "List invoices",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/summary": {
      "get": {
        "operationId": "InvoicesController_summary",
        "parameters": [
          {
            "name": "accept-language",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicingSummaryResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Get invoicing summary figures",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/drafts": {
      "post": {
        "operationId": "InvoicesController_createDrafts",
        "parameters": [
          {
            "name": "accept-language",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceDraftsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateInvoiceDraftsResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Create invoice drafts from billable candidates",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}": {
      "get": {
        "operationId": "InvoicesController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Get an invoice",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      },
      "patch": {
        "operationId": "InvoicesController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInvoiceDraftDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Update an invoice draft",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      },
      "delete": {
        "operationId": "InvoicesController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteInvoiceDraftDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Delete an invoice draft",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/lines": {
      "post": {
        "operationId": "InvoicesController_addLine",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddManualLineDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Add a manual line to an invoice draft",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/lines/{lineId}": {
      "patch": {
        "operationId": "InvoicesController_updateLine",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lineId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDraftLineDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Update an invoice draft line",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      },
      "delete": {
        "operationId": "InvoicesController_deleteLine",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lineId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Delete an invoice draft line",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/lines/reorder": {
      "post": {
        "operationId": "InvoicesController_reorderLines",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReorderDraftLinesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Reorder the lines of an invoice draft",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/review": {
      "post": {
        "operationId": "InvoicesController_review",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetInvoiceReviewDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Request or approve review of an invoice draft",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/issue": {
      "post": {
        "operationId": "InvoicesController_issueInvoice",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IssueInvoiceDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssueResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Issue an invoice",
        "description": "Burns a gapless invoice number; irreversible — corrections are credit notes. Requires an Idempotency-Key header when called with an API key.\n\n**Capability:** `payroll.run` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "payroll.run"
        ]
      }
    },
    "/v1/invoicing/invoices/{id}/credit-note": {
      "post": {
        "operationId": "InvoicesController_creditNote",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreditNoteDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditNoteResultDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Create a credit note for an issued invoice",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/dispatches": {
      "get": {
        "operationId": "InvoicesController_dispatches",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDispatchListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "List dispatch attempts for an invoice",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/dispatch": {
      "post": {
        "operationId": "InvoicesController_send",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DispatchRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDispatchViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Dispatch an invoice",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/dispatch/resend": {
      "post": {
        "operationId": "InvoicesController_resend",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DispatchRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDispatchViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Resend an invoice dispatch",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/dispatch/sync": {
      "post": {
        "operationId": "InvoicesController_syncDispatchStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceDispatchListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Sync e-invoice dispatch status from the operator",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/pdf": {
      "get": {
        "operationId": "InvoicesController_pdf",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "specification",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Download the invoice PDF",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/invoices/{id}/finvoice.xml": {
      "get": {
        "operationId": "InvoicesController_finvoice",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "Download the Finvoice 3.0 e-invoice XML",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/payments": {
      "get": {
        "operationId": "PaymentsController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "source",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "manual",
                "netvisor",
                "camt054"
              ]
            }
          },
          {
            "name": "unallocatedOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "invoiceId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "List payments",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "PaymentsController_record",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordPaymentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Record a payment",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/ar/aging": {
      "get": {
        "operationId": "PaymentsController_aging",
        "parameters": [
          {
            "name": "asOf",
            "required": false,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArAgingResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Get the aged receivables report",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/bank-imports": {
      "get": {
        "operationId": "PaymentsController_imports",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankImportListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "List bank file imports",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "PaymentsController_importBankFile",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportBankFileDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportResultViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Import a camt.054 bank file",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/customers/{id}/payment-behaviour": {
      "get": {
        "operationId": "PaymentsController_paymentBehaviour",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerPaymentBehaviourDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Get payment behaviour for a customer",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/customers/{id}/advance-balance": {
      "get": {
        "operationId": "PaymentsController_advanceBalance",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerAdvanceBalanceResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Get the unapplied advance balance for a customer",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/archive": {
      "get": {
        "operationId": "PaymentsController_exportArchive",
        "parameters": [
          {
            "name": "year",
            "required": true,
            "in": "query",
            "schema": {
              "minimum": 2000,
              "maximum": 2100,
              "type": "integer"
            }
          },
          {
            "name": "format",
            "required": false,
            "in": "query",
            "schema": {
              "default": "zip",
              "type": "string",
              "enum": [
                "zip"
              ]
            }
          },
          {
            "name": "profileId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "accept-language",
            "required": true,
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Download the invoice archive for a year",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/payments/{id}": {
      "get": {
        "operationId": "PaymentsController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Get a payment",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/payments/{id}/allocations": {
      "post": {
        "operationId": "PaymentsController_allocate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Caller-generated unique key (max 200 characters) that makes this money-document write exactly-once. Required for API-key callers; deduplicated per organisation for 24 h. Replaying the same key with the same body replays the stored response; a different body is refused with 409 `idempotency_key_reused`.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "payroll-run-2026-08-invoice-4711"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AllocatePaymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payments"
        ],
        "summary": "Allocate a payment to invoices",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/invoicing/recurring": {
      "get": {
        "operationId": "RecurringController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringScheduleListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "List recurring invoice schedules",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/invoicing/recurring/runs": {
      "get": {
        "operationId": "RecurringController_runs",
        "parameters": [
          {
            "name": "scheduleId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRunListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Invoices"
        ],
        "summary": "List recurring invoicing runs",
        "x-kelomo-capabilities": [
          "projects.manage",
          "payroll.run"
        ],
        "description": "**Capability:** `projects.manage` or `payroll.run` — an API key must carry one of these in its scope."
      }
    },
    "/v1/quotes": {
      "get": {
        "operationId": "QuotesController_list",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "updatedSince",
            "required": false,
            "in": "query",
            "schema": {
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "sent",
                "accepted",
                "declined",
                "expired"
              ]
            }
          },
          {
            "name": "q",
            "required": false,
            "in": "query",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "dealId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "templatesOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotePageResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "List quotes",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      },
      "post": {
        "operationId": "QuotesController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateQuoteDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "Create a quote draft",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/quotes/stats": {
      "get": {
        "operationId": "QuotesController_stats",
        "parameters": [
          {
            "name": "months",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 36,
              "default": 12,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteStatsResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "Get quote hit-rate statistics",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/quotes/{id}": {
      "get": {
        "operationId": "QuotesController_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "Get a quote",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/quotes/{id}/send": {
      "post": {
        "operationId": "QuotesController_send",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendQuoteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendQuoteResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "Send a quote to the customer",
        "description": "Freezes the draft, mints the customer share link and optionally emails it.\n\n**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ]
      }
    },
    "/v1/quotes/{id}/convert": {
      "post": {
        "operationId": "QuotesController_convert",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConvertQuoteDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "Convert an accepted quote into a project",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ],
        "description": "**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope."
      }
    },
    "/v1/quotes/{id}/pdf": {
      "get": {
        "operationId": "QuotesController_pdf",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Quotes"
        ],
        "summary": "Download a quote as a PDF",
        "description": "Binary response (application/pdf): the frozen snapshot, or a live preview for a draft.\n\n**Capability:** `crm.use` or `projects.manage` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "crm.use",
          "projects.manage"
        ]
      }
    },
    "/v1/me/balances": {
      "get": {
        "operationId": "InsightsController_myBalances",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceAccountsResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "List the caller’s balance accounts",
        "description": "Every balance account the caller holds (flex plus each banked-leave account) with its current standing. A closed per-member set — one row per account type the tenant runs — so it is not paginated.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/imports/customers": {
      "post": {
        "operationId": "ImportsController_customers",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateCustomersDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Imports"
        ],
        "summary": "Import customers in bulk",
        "description": "Answers 200 with one `results` row per submitted row — `{index, status, id, code}` where `index` is the 0-based position in the request, `status` is `created`, `skipped` or `error`, `id` is the created customer (null otherwise) and `code` a machine-readable reason (null when created). A partial import is a report, not an HTTP failure. Idempotent: a row whose `code` already exists is skipped (`code_already_in_use`), so re-running the same file creates nothing twice. Omit `code` and it is derived from the name, kept unique. Max 500 rows per batch — chunk larger files.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/imports/projects": {
      "post": {
        "operationId": "ImportsController_projects",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateProjectsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Imports"
        ],
        "summary": "Import projects in bulk",
        "description": "Answers 200 with one `results` row per submitted row — `{index, status, id, code}` where `index` is the 0-based position in the request, `status` is `created`, `skipped` or `error`, `id` is the created project (null otherwise) and `code` a machine-readable reason (null when created). A partial import is a report, not an HTTP failure. Idempotent: a row whose `code` already exists is skipped (`code_already_in_use`), so re-running the same file creates nothing twice. Max 500 rows per batch — chunk larger files.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/imports/tasks": {
      "post": {
        "operationId": "ImportsController_tasks",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateTasksDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Imports"
        ],
        "summary": "Import project tasks in bulk",
        "description": "Answers 200 with one `results` row per submitted row — `{index, status, id, code}` where `index` is the 0-based position in the request, `status` is `created` or `error`, `id` is the created task (null otherwise) and `code` a machine-readable reason (null when created). A partial import is a report, not an HTTP failure. Unlike the customer and project imports a task carries no tenant-unique key, so nothing is skipped: re-sending the same rows creates them again. Max 500 rows per batch — chunk larger files.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/imports/leads": {
      "post": {
        "operationId": "ImportsController_leads",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateLeadsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportWithDuplicatesResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Imports"
        ],
        "summary": "Import CRM leads in bulk",
        "description": "Answers 200 with one `results` row per submitted row — `{index, status, id, code}` where `index` is the 0-based position in the request, `status` is `created`, `skipped` or `error`, `id` is the created lead (null otherwise) and `code` a machine-readable reason (null when created). A partial import is a report, not an HTTP failure. Idempotent: a row matching an existing lead by e-mail or by title + company is skipped (`duplicate_lead`) and ALSO listed in `duplicates` with the matched `existingId` and the match basis, so re-running the same file creates nothing twice. Max 500 rows per batch — chunk larger files.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/imports/contacts": {
      "post": {
        "operationId": "ImportsController_contacts",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateContactsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkImportWithDuplicatesResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Imports"
        ],
        "summary": "Import customer contacts in bulk",
        "description": "Answers 200 with one `results` row per submitted row — `{index, status, id, code}` where `index` is the 0-based position in the request, `status` is `created`, `skipped` or `error`, `id` is the created contact (null otherwise) and `code` a machine-readable reason (null when created). A partial import is a report, not an HTTP failure. Idempotent: a row whose e-mail already exists on the same customer is skipped (`duplicate_contact`) and ALSO listed in `duplicates` with the matched `existingId`, so re-running the same file creates nothing twice. Max 500 rows per batch — chunk larger files.\n\n**Capability:** `org.admin` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "org.admin"
        ]
      }
    },
    "/v1/intake": {
      "get": {
        "operationId": "IntakeController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Intake"
        ],
        "summary": "List intake items",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "IntakeController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateIntakeItemDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeItemViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Intake"
        ],
        "summary": "Create an intake item",
        "description": "Any member may drop a work request in; a project manager triages it.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/intake/{id}/accept": {
      "post": {
        "operationId": "IntakeController_accept",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptIntakeItemDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeItemViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Intake"
        ],
        "summary": "Accept an intake item into a project",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/intake/{id}/route-to-lead": {
      "post": {
        "operationId": "IntakeController_routeToLead",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RouteIntakeToLeadDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeItemViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Intake"
        ],
        "summary": "Route an intake item to a CRM lead",
        "x-kelomo-capabilities": [
          "crm.admin"
        ],
        "description": "**Capability:** `crm.admin` — an API key must carry this in its scope."
      }
    },
    "/v1/intake/{id}/dismiss": {
      "post": {
        "operationId": "IntakeController_dismiss",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DismissIntakeItemDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeItemViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Intake"
        ],
        "summary": "Dismiss an intake item",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/change-orders": {
      "get": {
        "operationId": "ChangeOrdersController_list",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeOrderListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "List the change orders of a project",
        "x-kelomo-capabilities": [
          "projects.read"
        ],
        "description": "**Capability:** `projects.read` — an API key must carry this in its scope."
      },
      "post": {
        "operationId": "ChangeOrdersController_create",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChangeOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeOrderViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Create a change order on a project",
        "x-kelomo-capabilities": [
          "projects.manage"
        ],
        "description": "**Capability:** `projects.manage` — an API key must carry this in its scope."
      }
    },
    "/v1/projects/{id}/change-orders/{orderId}/approve": {
      "post": {
        "operationId": "ChangeOrdersController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "orderId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApproveChangeOrderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeOrderViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Projects"
        ],
        "summary": "Record a manual approval of a change order",
        "description": "Records an approval agreed outside the customer link (phone, on site).\n\n**Capability:** `projects.manage` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "projects.manage"
        ]
      }
    },
    "/v1/search": {
      "get": {
        "operationId": "SearchController_search",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "schema": {
              "minLength": 1,
              "maxLength": 120,
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 10,
              "default": 6,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Search"
        ],
        "summary": "Search across people, projects, tasks, customers and CRM records",
        "description": "One aggregate query over every entity family the caller may read. `limit` is a PER-GROUP cap (default 6, max 10), not a total — the response is bounded by design and therefore not cursor-paginated. Hits carry machine-readable ids only; a group the caller cannot read comes back as an empty array.\n\n**Capability:** `reports.team` or `crm.use` — an API key must carry one of these in its scope.",
        "x-kelomo-capabilities": [
          "reports.team",
          "crm.use"
        ]
      }
    },
    "/v1/expense-types": {
      "get": {
        "operationId": "ExpensesController_listTypes",
        "parameters": [
          {
            "name": "all",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseTypeListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "List the expense types a claim can use",
        "description": "The organisation’s expense catalogue: receipts, allowances and mileage types, with the unit each is priced in. Resolve the `expenseTypeId` a claim line needs from here — a mileage type takes the `mileage` block instead of an amount.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/expenses": {
      "get": {
        "operationId": "ExpensesController_listMine",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "draft",
                "submitted",
                "approved"
              ],
              "type": "string"
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "drive",
                "expense"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "List the caller’s own expense claims",
        "description": "Cursor-paginated, newest first. Optional `from`/`to` (expense date), `status` and `category` (`drive` = mileage lines, `expense` = everything else) narrow the set.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      },
      "post": {
        "operationId": "ExpensesController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExpenseDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseIdResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "Create a draft expense claim line for the caller",
        "description": "Creates the line as a DRAFT — it enters no approval queue and moves no money until it is submitted. Give `amountCents` for a receipt or allowance line, or the `mileage` block for a kilometre type (the server prices it from the organisation’s rates). `tripId` attaches the line to a trip, where it is decided with the trip rather than on its own.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/expenses/{id}": {
      "patch": {
        "operationId": "ExpensesController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateExpenseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "Update the caller’s draft expense claim line",
        "description": "Draft lines only — a submitted line is reopened first (409 otherwise).\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      },
      "delete": {
        "operationId": "ExpensesController_remove",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "Delete the caller’s draft expense claim line",
        "description": "Draft lines only.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/expenses/{id}/submit": {
      "post": {
        "operationId": "ExpensesController_submit",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "Submit the caller’s expense claim line for approval",
        "description": "Hands the line to the approver and freezes its amount. This is the step that turns a draft into a pending decision — leave it to the person whose claim it is unless your integration IS that person’s system of record.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/expenses/{id}/reopen": {
      "post": {
        "operationId": "ExpensesController_reopen",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Expenses"
        ],
        "summary": "Reopen the caller’s submitted expense claim line",
        "description": "Takes a submitted line back to draft. An approved line is not reopenable.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/expenses/{id}/approve": {
      "post": {
        "operationId": "ExpensesController_approve",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Approve an expense claim",
        "description": "The decision half of the `expense` rows in the approval queue. Requires supervisor authority over the claimant.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/expenses/{id}/return": {
      "post": {
        "operationId": "ExpensesController_returnToDraft",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReturnExpenseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOkResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureNotInPlan"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "Return an expense claim to the claimant",
        "description": "The other decision half of the `expense` rows in the approval queue: the line reopens as the claimant’s draft and the reason routes back to them. Requires supervisor authority over the claimant.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/me/punch/clock-in": {
      "post": {
        "operationId": "PunchesController_clockIn",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClockInDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchSessionStateDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Clock the caller in",
        "description": "Opens a punch session for the caller with their own key. Requires the organisation’s punch clock to be enabled (403 punch_clock_disabled otherwise) and no session already open (409 punch_session_open). Send a `clientPunchId` (UUID, generated ONCE per tap and reused on every retry): a replay of a punch that already landed returns the live session state instead of opening a second one, so a lost response can never double-punch. `occurredAt` may back-date the punch for an offline queue (at most 60 days back, at most 5 minutes into the future); omit it for server-now. Send `occurredAtSource: \"entered\"` when a PERSON typed that time rather than a clock observing it: it is recorded on the punch and shown to supervisors, the organisation may forbid it (403 backdated_punch_disabled), and it has its own, much shorter window (422 backdated_punch_too_old) — the 60-day tolerance is for an offline queue, not for repairing an old bookkeeping week. This is the self-service clock — a shared wall terminal uses the device realm and its own pairing credential, not a member key.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/punch/break-start": {
      "post": {
        "operationId": "PunchesController_breakStart",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PunchMarkDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchSessionStateDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Start a break on the caller’s open session",
        "description": "Needs an open session (409 no_open_session) that is not already on a break (409 already_on_break). Carries the break type: a `reasonId` from the organisation’s punch reasons, or `paid` directly. Idempotent through `clientPunchId` exactly like clock-in — a replayed break punch returns the live state instead of a second mark.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/punch/break-end": {
      "post": {
        "operationId": "PunchesController_breakEnd",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PunchMarkDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchSessionStateDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "End the break on the caller’s open session",
        "description": "Needs an open session that IS on a break (409 not_on_break). Idempotent through `clientPunchId` like the other punches.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/punch/absence-gap": {
      "post": {
        "operationId": "PunchesController_absenceGap",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordAbsenceGapDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchSessionStateDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Explain the caller’s unexplained past days as an absence",
        "description": "Records the span `GET /me/punch/state` offered in `returnGap` as leave, using a punch reason the organisation marked usable on clock-in (422 punch_reason_not_usable_on_clock_in otherwise). Send back the span you SHOWED the member: a span reaching today or the future, or longer than 31 days, is refused (422 punch_return_gap_invalid) — those belong to the planned leave flow and to the supervisor. Days already covered by an existing absence are skipped, never overwritten. Returns the refreshed session state, whose `returnGap` is then empty.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/punch/set-allocation": {
      "post": {
        "operationId": "PunchesController_setAllocation",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPunchAllocationDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchSessionStateDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Retarget the caller’s open session to another project or task",
        "description": "Rewrites the open session’s project / cost-centre allocation (or `taskId`) mid-shift, so the draft day the session materialises books to the new target. Needs an open session (409 no_open_session). A full replacement of the session’s allocation hint — sending it twice leaves the same result — and it touches only a session whose day is still a draft, never a confirmed record.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/punch/clock-out": {
      "post": {
        "operationId": "PunchesController_clockOut",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PunchMarkDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkDayDetailResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Clock the caller out",
        "description": "Closes the open session (409 no_open_session if there is none) and materialises the session into the DRAFT work day it produced, which is returned so the caller can review and confirm it. The day is a draft, never a confirmed record — confirmation is a separate, explicit act. Idempotent through `clientPunchId`: a replayed clock-out reads back the same materialised day instead of failing. `reasonId` carries the day-ending reason when the organisation asks for one (422 punch_reason_required). A member who forgot to clock out may send the time they finished as `occurredAt` together with `occurredAtSource: \"entered\"`; see the clock-in description for the switch and the window that govern it.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/me/punch/day/{date}/rebuild": {
      "post": {
        "operationId": "PunchesController_rebuildDay",
        "parameters": [
          {
            "name": "date",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PunchDayViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Me"
        ],
        "summary": "Rebuild the caller’s work day from its recorded punches",
        "description": "Re-derives the day’s DRAFT from the punches it already holds. Punches recorded while the day could not take them (an approved leave day, a confirmed record, hand-entered rows) stay in the stream as evidence; this is what turns them back into a work day once the obstacle is gone. Refused while the obstacle stands (409 with the lock code: day_on_approved_leave, day_confirmed_locked, day_has_manual_entries, day_has_duration_entries) and when the day holds no punches to derive from (422 punch_day_not_punched). Never touches a confirmed record — the day is rebuilt as a draft, exactly as a clock-out would.\n\n**Capability:** none — the operation acts as the authenticated member and its authorisation is row-level (ownership, the approver line, project membership). An API key with an empty scope reaches it.",
        "x-kelomo-capabilities": []
      }
    },
    "/v1/team/presence": {
      "get": {
        "operationId": "PunchPresenceController_presence",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TeamPresenceViewDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Presence"
        ],
        "summary": "List who is on the clock right now",
        "description": "Requires the tenant’s presence board to be enabled; scoped to the caller’s reports.\n\n**Capability:** `worktime.supervise` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ]
      }
    },
    "/v1/payroll-locks": {
      "get": {
        "operationId": "PayrollLocksController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayrollPeriodLockListResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Payroll exports"
        ],
        "summary": "List payroll period locks",
        "x-kelomo-capabilities": [
          "payroll.run"
        ],
        "description": "**Capability:** `payroll.run` — an API key must carry this in its scope."
      }
    },
    "/v1/reports": {
      "get": {
        "operationId": "PublicReportsController_listTypes",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicReportTypesResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Reports"
        ],
        "summary": "List report types available to the caller",
        "description": "The closed report-type catalogue filtered by the caller’s capabilities and the tenant’s enabled modules. Types carrying person-level absence/health data are never available over the API.\n\n**Capability:** `reports.team` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "reports.team"
        ]
      }
    },
    "/v1/reports/{type}": {
      "get": {
        "operationId": "PublicReportsController_generate",
        "parameters": [
          {
            "name": "type",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "schema": {
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "type": "string"
            }
          },
          {
            "name": "format",
            "required": false,
            "in": "query",
            "schema": {
              "default": "pdf",
              "type": "string",
              "enum": [
                "pdf",
                "xlsx",
                "csv"
              ]
            }
          },
          {
            "name": "groupId",
            "required": false,
            "in": "query",
            "schema": {
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
              "type": "string"
            }
          },
          {
            "name": "locale",
            "required": false,
            "in": "query",
            "schema": {
              "default": "fi",
              "type": "string",
              "enum": [
                "fi",
                "sv",
                "en"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Reports"
        ],
        "summary": "Generate a report as a file",
        "description": "Renders one report type as PDF, XLSX or CSV for the inclusive period from–to (max 366 days). Snapshot-style types (hr headcount, qualification matrix, leave valuations) read the period end as their valuation date. The caller must hold the type’s capability; 403 report_type_not_public for types excluded from the API.\n\n**Capability:** `reports.team` — an API key must carry this in its scope.",
        "x-kelomo-capabilities": [
          "reports.team"
        ]
      }
    },
    "/v1/team/approvals": {
      "get": {
        "operationId": "ApprovalsController_queue",
        "parameters": [
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "type": "integer"
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "work_week",
                "expense",
                "trip",
                "leave",
                "swap",
                "training",
                "open_shift_claim",
                "leave_save"
              ]
            }
          },
          {
            "name": "today",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lookbackDays",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalQueueResponseDto"
                }
              }
            },
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "tags": [
          "Approvals"
        ],
        "summary": "List items awaiting the caller’s approval decision",
        "x-kelomo-capabilities": [
          "worktime.supervise"
        ],
        "description": "**Capability:** `worktime.supervise` — an API key must carry this in its scope."
      }
    }
  },
  "info": {
    "title": "Kelomo Public API",
    "version": "1.0",
    "description": "The published Kelomo REST API. Authenticate with an API key (`Authorization: Bearer kelomo_…`) minted in Settings → API access.\n\n**Reading this as raw JSON?** The same contract rendered, with search, examples and guides, is at https://kelomo.fi/developers/reference/\n\n- **Pagination.** List endpoints are cursor-paginated: `cursor`, `limit` → `pageInfo.nextCursor`. Lists with a real change stamp also accept `updatedSince` for incremental mirroring.\n- **Errors.** Every failure is an RFC 9457 `application/problem+json` document with a stable machine-readable `code`. Branch on `code`, never on `title` or `detail`. The catalogue is at https://kelomo.fi/developers/guides/error-codes/.\n- **Capabilities.** Each operation states the capability its key scope must contain (`x-kelomo-capabilities`, repeated in the description). Choosing too narrow a scope shows up as 403 `insufficient_role`.\n- **Idempotency.** Money-document writes require an `Idempotency-Key` header from API-key callers; the key deduplicates for 24 h.\n- **Tracing.** Every response carries `X-Request-Id`, mirrored in the problem body as `requestId`. Log it — support asks for it.\n- **Rate limits.** 600 requests/minute per key and 3000/minute per organisation; `X-RateLimit-*` and `RateLimit-Policy` report the binding budget, and a 429 carries `Retry-After`."
  },
  "tags": [
    {
      "name": "Me",
      "description": "The authenticated member’s own data: overview, entitlements, work days, balances and requests. Reachable with ANY key — an empty-scope key is exactly this surface."
    },
    {
      "name": "Members",
      "description": "Members of the organisation (the workforce roster) and their full provisioning lifecycle: create (one or in bulk), invite, update, place in planning units, record the employment window and terms, terminate, deactivate and reactivate. The sensitive personal tier (identity number, bank account, home address), versioned payroll configuration and GDPR erasure are deliberately not reachable here."
    },
    {
      "name": "Search",
      "description": "One aggregate quick-search across every entity family the caller may read. Groups the caller has no access to come back empty, so the response shape leaks nothing."
    },
    {
      "name": "Work days",
      "description": "Work-time bookkeeping: work days, entries and their confirmation lifecycle — including the supervisor-side write that imports a workforce’s hours. Drafts are freely rewritten; a confirmed or approved day is never edited in place, only moved by a lifecycle action (reopen, return, correct)."
    },
    {
      "name": "Presence",
      "description": "Who is at work right now — punch-derived presence."
    },
    {
      "name": "Balances",
      "description": "Balance accounts (flex, overtime, banked leave) and their transactions."
    },
    {
      "name": "Shifts",
      "description": "Planned shifts, publish events, open shifts and shift swaps."
    },
    {
      "name": "Absences",
      "description": "Absence periods, policies and leave balances. Absence types are masked by sensitivity exactly as in the UI."
    },
    {
      "name": "Trips",
      "description": "Travel claims: the caller’s own trips, their travel days (per diem, night allowance, free meals) and the claim lifecycle. A trip is created as a draft and reaches an approver only when it is submitted. Requires the travel-and-expense module (402 `feature_not_in_plan` otherwise)."
    },
    {
      "name": "Expenses",
      "description": "Expense claims: the caller’s own receipt, allowance and mileage lines, the expense-type catalogue they are priced from, and the claim lifecycle. Approving them is on the Approvals surface. Requires the travel-and-expense module (402 `feature_not_in_plan` otherwise)."
    },
    {
      "name": "Approvals",
      "description": "The unified approval queue: work days, absences, expenses and other pending decisions."
    },
    {
      "name": "Payroll exports",
      "description": "Payroll export batches: the frozen material handed to the payroll system."
    },
    {
      "name": "Billing exports",
      "description": "Billing export batches: invoice material handed to an external invoicing system."
    },
    {
      "name": "Invoices",
      "description": "Invoices and credit notes: drafting, issuing, dispatch (e-invoice/email) and renditions (PDF, Finvoice XML)."
    },
    {
      "name": "Payments",
      "description": "Accounts receivable: payments, allocations, bank imports (camt.054) and the AR aging view."
    },
    {
      "name": "Projects",
      "description": "Projects, phases, change orders, installments and purchases."
    },
    {
      "name": "Tasks",
      "description": "Work management tasks and their lifecycle."
    },
    {
      "name": "Quotes",
      "description": "Quotes: drafting, sending, customer decisions and conversion to projects."
    },
    {
      "name": "Customers",
      "description": "The customer register shared by CRM, projects and invoicing."
    },
    {
      "name": "CRM",
      "description": "Sales: leads, deals, pipelines, activities and the customer 360 view."
    },
    {
      "name": "Reports",
      "description": "Generated reports: a closed catalogue of report types rendered as JSON, PDF, XLSX or CSV."
    },
    {
      "name": "Catalogs",
      "description": "Tenant configuration catalogues: planning units, shift types, entry types, dimensions and staff groups."
    },
    {
      "name": "Imports",
      "description": "Migration bulk imports: the admin-only data on-ramp. A batch always answers 200 with a per-row outcome, and re-running the same rows skips what already exists."
    },
    {
      "name": "Integration events",
      "description": "The tenant’s integration-event log: the same truth webhooks fan out, readable for reconciliation and polling."
    },
    {
      "name": "Webhooks",
      "description": "Outgoing webhook endpoints, delivery log and signing-secret management."
    },
    {
      "name": "API keys",
      "description": "API key management (human sessions only — a key cannot manage keys)."
    },
    {
      "name": "Audit",
      "description": "The administrative audit trail."
    },
    {
      "name": "Attachments",
      "description": "File attachments: presigned upload, finalize and download URLs."
    },
    {
      "name": "Intake",
      "description": "Inbound work requests (the front door for “create a request from a form”)."
    }
  ],
  "servers": [
    {
      "url": "https://api.kelomo.fi"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "AuditEventPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "action": {
                  "type": "string"
                },
                "entity": {
                  "type": "string"
                },
                "entityId": {
                  "type": "string"
                },
                "actorName": {
                  "type": "string",
                  "nullable": true
                },
                "viaApiKey": {
                  "type": "boolean"
                },
                "occurredAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                }
              },
              "required": [
                "id",
                "action",
                "entity",
                "entityId",
                "actorName",
                "viaApiKey",
                "occurredAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "InitiateAttachmentDto": {
        "type": "object",
        "properties": {
          "ownerType": {
            "type": "string",
            "enum": [
              "expense",
              "trip",
              "employment",
              "employee_profile",
              "membership_skill",
              "checklist_run",
              "compliance_item",
              "membership",
              "absence_period",
              "task",
              "project",
              "purchase",
              "case_note",
              "training_participation",
              "safety_incident",
              "candidate",
              "whistleblowing_report",
              "deal",
              "quote",
              "service_request",
              "emergency_work_notice",
              "invoice"
            ]
          },
          "ownerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "originalName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "contentType": {
            "type": "string",
            "enum": [
              "image/jpeg",
              "image/png",
              "image/webp",
              "image/heic",
              "application/pdf",
              "application/msword",
              "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
              "application/vnd.ms-excel",
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
              "application/vnd.ms-powerpoint",
              "application/vnd.openxmlformats-officedocument.presentationml.presentation",
              "application/vnd.oasis.opendocument.text",
              "application/vnd.oasis.opendocument.spreadsheet",
              "application/vnd.oasis.opendocument.presentation",
              "text/csv",
              "text/plain"
            ]
          },
          "sizeBytes": {
            "type": "integer",
            "exclusiveMinimum": true,
            "maximum": 9007199254740991,
            "minimum": 0
          },
          "category": {
            "type": "string",
            "enum": [
              "contract",
              "certificate",
              "id_document",
              "payroll",
              "policy",
              "onboarding",
              "other",
              "offer",
              "plan",
              "photo",
              "minutes",
              "report"
            ]
          },
          "documentCategoryId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "ownerType",
          "ownerId",
          "originalName",
          "contentType",
          "sizeBytes"
        ]
      },
      "InitiateAttachmentResponseDto": {
        "type": "object",
        "properties": {
          "attachmentId": {
            "type": "string"
          },
          "upload": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string"
              },
              "method": {
                "type": "string",
                "enum": [
                  "PUT"
                ]
              },
              "headers": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              },
              "expiresInSeconds": {
                "type": "integer",
                "exclusiveMinimum": true,
                "maximum": 9007199254740991,
                "minimum": 0
              }
            },
            "required": [
              "url",
              "method",
              "headers",
              "expiresInSeconds"
            ]
          }
        },
        "required": [
          "attachmentId",
          "upload"
        ]
      },
      "AttachmentViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "ownerType": {
            "type": "string",
            "enum": [
              "expense",
              "trip",
              "employment",
              "employee_profile",
              "membership_skill",
              "checklist_run",
              "compliance_item",
              "membership",
              "absence_period",
              "task",
              "project",
              "purchase",
              "case_note",
              "training_participation",
              "safety_incident",
              "candidate",
              "whistleblowing_report",
              "deal",
              "quote",
              "service_request",
              "emergency_work_notice",
              "invoice"
            ]
          },
          "ownerId": {
            "type": "string"
          },
          "originalName": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "category": {
            "type": "string",
            "enum": [
              "contract",
              "certificate",
              "id_document",
              "payroll",
              "policy",
              "onboarding",
              "other",
              "offer",
              "plan",
              "photo",
              "minutes",
              "report",
              null
            ],
            "nullable": true
          },
          "documentCategoryId": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "scanning",
              "ready",
              "rejected"
            ]
          },
          "uploadedByMembershipId": {
            "type": "string",
            "nullable": true
          },
          "uploadedAt": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          },
          "signingStatus": {
            "type": "string",
            "enum": [
              "none",
              "pending",
              "signed",
              "declined",
              "cancelled"
            ]
          },
          "signedAt": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "ownerType",
          "ownerId",
          "originalName",
          "contentType",
          "sizeBytes",
          "category",
          "documentCategoryId",
          "status",
          "uploadedByMembershipId",
          "uploadedAt",
          "createdAt",
          "signingStatus",
          "signedAt"
        ]
      },
      "AttachmentListResponseDto": {
        "type": "object",
        "properties": {
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "ownerType": {
                  "type": "string",
                  "enum": [
                    "expense",
                    "trip",
                    "employment",
                    "employee_profile",
                    "membership_skill",
                    "checklist_run",
                    "compliance_item",
                    "membership",
                    "absence_period",
                    "task",
                    "project",
                    "purchase",
                    "case_note",
                    "training_participation",
                    "safety_incident",
                    "candidate",
                    "whistleblowing_report",
                    "deal",
                    "quote",
                    "service_request",
                    "emergency_work_notice",
                    "invoice"
                  ]
                },
                "ownerId": {
                  "type": "string"
                },
                "originalName": {
                  "type": "string"
                },
                "contentType": {
                  "type": "string"
                },
                "sizeBytes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "category": {
                  "type": "string",
                  "enum": [
                    "contract",
                    "certificate",
                    "id_document",
                    "payroll",
                    "policy",
                    "onboarding",
                    "other",
                    "offer",
                    "plan",
                    "photo",
                    "minutes",
                    "report",
                    null
                  ],
                  "nullable": true
                },
                "documentCategoryId": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "scanning",
                    "ready",
                    "rejected"
                  ]
                },
                "uploadedByMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "uploadedAt": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "signingStatus": {
                  "type": "string",
                  "enum": [
                    "none",
                    "pending",
                    "signed",
                    "declined",
                    "cancelled"
                  ]
                },
                "signedAt": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "ownerType",
                "ownerId",
                "originalName",
                "contentType",
                "sizeBytes",
                "category",
                "documentCategoryId",
                "status",
                "uploadedByMembershipId",
                "uploadedAt",
                "createdAt",
                "signingStatus",
                "signedAt"
              ]
            }
          }
        },
        "required": [
          "attachments"
        ]
      },
      "AttachmentDownloadResponseDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "expiresInSeconds": {
            "type": "integer",
            "exclusiveMinimum": true,
            "maximum": 9007199254740991,
            "minimum": 0
          }
        },
        "required": [
          "url",
          "expiresInSeconds"
        ]
      },
      "WorkDayRangeResponseDto": {
        "type": "object",
        "properties": {
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "proposed",
                    "draft",
                    "confirmed",
                    "approved",
                    "exported"
                  ]
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "breaks": {
                  "default": [],
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                        "nullable": true
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "breakTypeId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                        "nullable": true
                      },
                      "paidMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "id",
                      "startMinutes",
                      "endMinutes",
                      "breakTypeId",
                      "paidMinutes"
                    ]
                  }
                },
                "paidBreakMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "workMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "creditedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "appliedCreditMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "uncountedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "rawDeltaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "balanceDeltaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "attentionThresholdMinutes": {
                  "default": 15,
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 480
                },
                "runningBalanceMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "overtimeMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "dayType": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{1,49}$"
                    },
                    "nameFi": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameSv": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameEn": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn"
                  ],
                  "nullable": true
                },
                "absencePeriod": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "draft",
                        "submitted",
                        "approved",
                        "rejected",
                        "cancelled",
                        "withdrawn"
                      ]
                    },
                    "workflowMode": {
                      "type": "string",
                      "enum": [
                        "request",
                        "notification",
                        "employer_assignment"
                      ]
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "status",
                    "workflowMode",
                    "nameFi",
                    "nameSv",
                    "nameEn"
                  ],
                  "nullable": true
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "worktime-model",
                          "calendar-event",
                          "planned-shift",
                          "punch",
                          "learned-baseline"
                        ]
                      },
                      "versionId": {
                        "type": "string"
                      },
                      "eventId": {
                        "type": "string"
                      },
                      "shiftId": {
                        "type": "string"
                      },
                      "punchSessionId": {
                        "type": "string"
                      },
                      "weekday": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 7
                      }
                    },
                    "required": [
                      "type"
                    ]
                  }
                },
                "deviations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "overlong-day",
                          "short-day",
                          "missing-break",
                          "missing-second-break",
                          "fragmented-break",
                          "break-at-day-edge",
                          "flex-limit-exceeded",
                          "outside-flex-window",
                          "outside-allowed-window",
                          "work-on-day-off",
                          "entry-over-max-duration",
                          "insufficient-daily-rest",
                          "insufficient-weekly-rest"
                        ]
                      },
                      "deltaMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "severity": {
                        "type": "string",
                        "enum": [
                          "advisory",
                          "info"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "deltaMinutes"
                    ]
                  }
                },
                "overtimeDisposition": {
                  "default": "flex",
                  "type": "string",
                  "enum": [
                    "flex",
                    "payout",
                    "ignore",
                    "bank"
                  ]
                },
                "bankAccountTypeId": {
                  "type": "string",
                  "default": null,
                  "nullable": true
                },
                "entries": {
                  "default": [],
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "entryTypeId": {
                        "type": "string"
                      },
                      "entryTypeCode": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{1,49}$"
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 2879,
                        "nullable": true
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880,
                        "nullable": true
                      },
                      "durationMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "note": {
                        "type": "string",
                        "nullable": true
                      },
                      "billable": {
                        "type": "boolean"
                      },
                      "billingBaseMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "allocations": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "dimensionId": {
                              "type": "string"
                            },
                            "valueId": {
                              "type": "string"
                            },
                            "valueCode": {
                              "type": "string"
                            },
                            "valueName": {
                              "type": "string"
                            },
                            "weightBp": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            }
                          },
                          "required": [
                            "dimensionId",
                            "valueId",
                            "valueCode",
                            "valueName",
                            "weightBp"
                          ]
                        }
                      }
                    },
                    "required": [
                      "id",
                      "entryTypeId",
                      "entryTypeCode",
                      "startMinutes",
                      "endMinutes",
                      "note",
                      "billable",
                      "allocations"
                    ]
                  }
                },
                "proposedEntries": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "entryTypeId": {
                        "type": "string"
                      },
                      "billable": {
                        "type": "boolean"
                      },
                      "allocations": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "dimensionId": {
                              "type": "string"
                            },
                            "valueId": {
                              "type": "string"
                            },
                            "valueCode": {
                              "type": "string"
                            },
                            "valueName": {
                              "type": "string"
                            },
                            "weightBp": {
                              "default": 10000,
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "source": {
                              "type": "string",
                              "enum": [
                                "calendar",
                                "geofence",
                                "task",
                                "baseline",
                                "default"
                              ]
                            },
                            "confidence": {
                              "type": "string",
                              "enum": [
                                "high",
                                "medium",
                                "low"
                              ]
                            }
                          },
                          "required": [
                            "dimensionId",
                            "valueId",
                            "valueCode",
                            "valueName",
                            "source",
                            "confidence"
                          ]
                        }
                      },
                      "confidence": {
                        "type": "string",
                        "enum": [
                          "high",
                          "medium",
                          "low"
                        ]
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "entryTypeId",
                      "billable",
                      "allocations",
                      "confidence"
                    ]
                  }
                },
                "expectedSource": {
                  "type": "string",
                  "nullable": true
                },
                "expectedWindow": {
                  "type": "object",
                  "properties": {
                    "startMinutes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 1440
                    },
                    "endMinutes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 1440
                    },
                    "breakMinutes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "startMinutes",
                    "endMinutes",
                    "breakMinutes"
                  ],
                  "nullable": true
                },
                "proposalDismissed": {
                  "type": "boolean"
                },
                "updatedAt": {
                  "type": "string",
                  "default": null,
                  "nullable": true
                },
                "returnReason": {
                  "type": "string",
                  "nullable": true
                },
                "confirmationOptional": {
                  "type": "boolean"
                },
                "confirmedOnBehalf": {
                  "type": "boolean"
                },
                "autoConfirmed": {
                  "type": "boolean"
                },
                "confidence": {
                  "type": "object",
                  "properties": {
                    "level": {
                      "type": "string",
                      "enum": [
                        "high",
                        "medium",
                        "low"
                      ]
                    },
                    "reasons": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "level",
                    "reasons"
                  ]
                },
                "supplements": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "supplementTypeId": {
                        "type": "string"
                      },
                      "supplementTypeCode": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{1,49}$"
                      },
                      "nameFi": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "nameSv": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "nameEn": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "valueKind": {
                        "type": "string",
                        "enum": [
                          "flag",
                          "count",
                          "hours",
                          "amount"
                        ]
                      },
                      "unit": {
                        "type": "string",
                        "enum": [
                          "hours",
                          "pieces",
                          "days",
                          "decimal"
                        ]
                      },
                      "exportMode": {
                        "type": "string",
                        "enum": [
                          "passthrough",
                          "tesOnly"
                        ]
                      },
                      "quantity": {
                        "type": "number"
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440,
                        "nullable": true
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440,
                        "nullable": true
                      },
                      "comment": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "supplementTypeId",
                      "supplementTypeCode",
                      "nameFi",
                      "nameSv",
                      "nameEn",
                      "valueKind",
                      "unit",
                      "exportMode",
                      "quantity",
                      "startMinutes",
                      "endMinutes",
                      "comment"
                    ]
                  }
                },
                "standby": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "periodId": {
                        "type": "string"
                      },
                      "standbyType": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string",
                            "pattern": "^[a-z][a-z0-9_]{1,49}$"
                          },
                          "nameFi": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          },
                          "nameSv": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          },
                          "nameEn": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          },
                          "worktimeFraction": {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 1
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "nameFi",
                          "nameSv",
                          "nameEn",
                          "worktimeFraction"
                        ]
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 1440
                      }
                    },
                    "required": [
                      "periodId",
                      "standbyType",
                      "startMinutes",
                      "endMinutes"
                    ]
                  }
                },
                "governingShiftType": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    },
                    "shortCode": {
                      "type": "string"
                    },
                    "color": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "plan",
                        "walk-up",
                        "rule",
                        "model-default",
                        "override"
                      ]
                    }
                  },
                  "required": [
                    "nameFi",
                    "nameSv",
                    "nameEn",
                    "shortCode",
                    "color"
                  ]
                },
                "plannedShift": {
                  "type": "object",
                  "properties": {
                    "startMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    },
                    "endMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    },
                    "breakMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "targetMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "person-shift",
                        "group-shift"
                      ]
                    },
                    "shiftType": {
                      "type": "object",
                      "properties": {
                        "nameFi": {
                          "type": "string"
                        },
                        "nameSv": {
                          "type": "string"
                        },
                        "nameEn": {
                          "type": "string"
                        },
                        "shortCode": {
                          "type": "string"
                        },
                        "color": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "nameFi",
                        "nameSv",
                        "nameEn",
                        "shortCode",
                        "color"
                      ],
                      "nullable": true
                    }
                  },
                  "required": [
                    "startMinutes",
                    "endMinutes",
                    "breakMinutes",
                    "targetMinutes",
                    "source",
                    "shiftType"
                  ]
                }
              },
              "required": [
                "workDate",
                "status",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "workMinutes",
                "creditedMinutes",
                "targetMinutes",
                "balanceDeltaMinutes",
                "runningBalanceMinutes",
                "overtimeMinutes",
                "dayType",
                "sources",
                "deviations",
                "expectedSource"
              ]
            }
          },
          "summary": {
            "type": "object",
            "properties": {
              "totalWorkMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalTargetMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalAppliedCreditMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalUncountedMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalPaidBreakMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalUnpaidBreakMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalUnitemisedBreakMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "deltaMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "recordedDeltaMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "balanceBeforeMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "projectedBalanceMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "overtimeMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "totalWorkMinutes",
              "totalTargetMinutes",
              "deltaMinutes",
              "balanceBeforeMinutes",
              "projectedBalanceMinutes",
              "overtimeMinutes"
            ]
          },
          "worktimeRegime": {
            "default": "standard",
            "type": "string",
            "enum": [
              "standard",
              "flexwork",
              "period"
            ]
          },
          "currentWorktimePercentBp": {
            "type": "integer",
            "exclusiveMinimum": true,
            "maximum": 9007199254740991,
            "minimum": 0
          }
        },
        "required": [
          "days",
          "summary"
        ]
      },
      "WorkDayDetailResponseDto": {
        "type": "object",
        "properties": {
          "workDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "proposed",
              "draft",
              "confirmed",
              "approved",
              "exported"
            ]
          },
          "startMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1440,
            "nullable": true
          },
          "endMinutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2880,
            "nullable": true
          },
          "breakMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "breaks": {
            "default": [],
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "breakTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "paidMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "startMinutes",
                "endMinutes",
                "breakTypeId",
                "paidMinutes"
              ]
            }
          },
          "paidBreakMinutes": {
            "default": 0,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "workMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "creditedMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "targetMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "appliedCreditMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "uncountedMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "rawDeltaMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "balanceDeltaMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "attentionThresholdMinutes": {
            "default": 15,
            "type": "integer",
            "minimum": 0,
            "maximum": 480
          },
          "runningBalanceMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "overtimeMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "dayType": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]{1,49}$"
              },
              "nameFi": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "nameSv": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "nameEn": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              }
            },
            "required": [
              "id",
              "code",
              "nameFi",
              "nameSv",
              "nameEn"
            ],
            "nullable": true
          },
          "absencePeriod": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "status": {
                "type": "string",
                "enum": [
                  "draft",
                  "submitted",
                  "approved",
                  "rejected",
                  "cancelled",
                  "withdrawn"
                ]
              },
              "workflowMode": {
                "type": "string",
                "enum": [
                  "request",
                  "notification",
                  "employer_assignment"
                ]
              },
              "nameFi": {
                "type": "string"
              },
              "nameSv": {
                "type": "string"
              },
              "nameEn": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "status",
              "workflowMode",
              "nameFi",
              "nameSv",
              "nameEn"
            ],
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "worktime-model",
                    "calendar-event",
                    "planned-shift",
                    "punch",
                    "learned-baseline"
                  ]
                },
                "versionId": {
                  "type": "string"
                },
                "eventId": {
                  "type": "string"
                },
                "shiftId": {
                  "type": "string"
                },
                "punchSessionId": {
                  "type": "string"
                },
                "weekday": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 7
                }
              },
              "required": [
                "type"
              ]
            }
          },
          "deviations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "overlong-day",
                    "short-day",
                    "missing-break",
                    "missing-second-break",
                    "fragmented-break",
                    "break-at-day-edge",
                    "flex-limit-exceeded",
                    "outside-flex-window",
                    "outside-allowed-window",
                    "work-on-day-off",
                    "entry-over-max-duration",
                    "insufficient-daily-rest",
                    "insufficient-weekly-rest"
                  ]
                },
                "deltaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "advisory",
                    "info"
                  ]
                }
              },
              "required": [
                "type",
                "deltaMinutes"
              ]
            }
          },
          "overtimeDisposition": {
            "default": "flex",
            "type": "string",
            "enum": [
              "flex",
              "payout",
              "ignore",
              "bank"
            ]
          },
          "bankAccountTypeId": {
            "type": "string",
            "default": null,
            "nullable": true
          },
          "entries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "entryTypeId": {
                  "type": "string"
                },
                "entryTypeCode": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,49}$"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2879,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "durationMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "default": null,
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "billable": {
                  "type": "boolean"
                },
                "billingBaseMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "default": null,
                  "nullable": true
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueCode": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string"
                      },
                      "weightBp": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueCode",
                      "valueName",
                      "weightBp"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "entryTypeId",
                "entryTypeCode",
                "startMinutes",
                "endMinutes",
                "note",
                "billable",
                "allocations"
              ]
            }
          },
          "proposedEntries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "entryTypeId": {
                  "type": "string"
                },
                "billable": {
                  "type": "boolean"
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueCode": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string"
                      },
                      "weightBp": {
                        "default": 10000,
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "calendar",
                          "geofence",
                          "task",
                          "baseline",
                          "default"
                        ]
                      },
                      "confidence": {
                        "type": "string",
                        "enum": [
                          "high",
                          "medium",
                          "low"
                        ]
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueCode",
                      "valueName",
                      "source",
                      "confidence"
                    ]
                  }
                },
                "confidence": {
                  "type": "string",
                  "enum": [
                    "high",
                    "medium",
                    "low"
                  ]
                }
              },
              "required": [
                "startMinutes",
                "endMinutes",
                "entryTypeId",
                "billable",
                "allocations",
                "confidence"
              ]
            }
          },
          "expectedSource": {
            "type": "string",
            "nullable": true
          },
          "expectedWindow": {
            "type": "object",
            "properties": {
              "startMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1440
              },
              "endMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1440
              },
              "breakMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "startMinutes",
              "endMinutes",
              "breakMinutes"
            ],
            "nullable": true
          },
          "proposalDismissed": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string",
            "default": null,
            "nullable": true
          },
          "returnReason": {
            "type": "string",
            "nullable": true
          },
          "confirmationOptional": {
            "type": "boolean"
          },
          "confirmedOnBehalf": {
            "type": "boolean"
          },
          "autoConfirmed": {
            "type": "boolean"
          },
          "confidence": {
            "type": "object",
            "properties": {
              "level": {
                "type": "string",
                "enum": [
                  "high",
                  "medium",
                  "low"
                ]
              },
              "reasons": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "level",
              "reasons"
            ]
          },
          "supplements": {
            "default": [],
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "supplementTypeId": {
                  "type": "string"
                },
                "supplementTypeCode": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,49}$"
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "valueKind": {
                  "type": "string",
                  "enum": [
                    "flag",
                    "count",
                    "hours",
                    "amount"
                  ]
                },
                "unit": {
                  "type": "string",
                  "enum": [
                    "hours",
                    "pieces",
                    "days",
                    "decimal"
                  ]
                },
                "exportMode": {
                  "type": "string",
                  "enum": [
                    "passthrough",
                    "tesOnly"
                  ]
                },
                "quantity": {
                  "type": "number"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "comment": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "supplementTypeId",
                "supplementTypeCode",
                "nameFi",
                "nameSv",
                "nameEn",
                "valueKind",
                "unit",
                "exportMode",
                "quantity",
                "startMinutes",
                "endMinutes",
                "comment"
              ]
            }
          },
          "standby": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "periodId": {
                  "type": "string"
                },
                "standbyType": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{1,49}$"
                    },
                    "nameFi": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameSv": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameEn": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "worktimeFraction": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn",
                    "worktimeFraction"
                  ]
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 1440
                }
              },
              "required": [
                "periodId",
                "standbyType",
                "startMinutes",
                "endMinutes"
              ]
            }
          },
          "governingShiftType": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "nameFi": {
                "type": "string"
              },
              "nameSv": {
                "type": "string"
              },
              "nameEn": {
                "type": "string"
              },
              "shortCode": {
                "type": "string"
              },
              "color": {
                "type": "string"
              },
              "source": {
                "type": "string",
                "enum": [
                  "plan",
                  "walk-up",
                  "rule",
                  "model-default",
                  "override"
                ]
              }
            },
            "required": [
              "nameFi",
              "nameSv",
              "nameEn",
              "shortCode",
              "color"
            ]
          },
          "plannedShift": {
            "type": "object",
            "properties": {
              "startMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "endMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "breakMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "targetMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "source": {
                "type": "string",
                "enum": [
                  "person-shift",
                  "group-shift"
                ]
              },
              "shiftType": {
                "type": "object",
                "properties": {
                  "nameFi": {
                    "type": "string"
                  },
                  "nameSv": {
                    "type": "string"
                  },
                  "nameEn": {
                    "type": "string"
                  },
                  "shortCode": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                },
                "required": [
                  "nameFi",
                  "nameSv",
                  "nameEn",
                  "shortCode",
                  "color"
                ],
                "nullable": true
              }
            },
            "required": [
              "startMinutes",
              "endMinutes",
              "breakMinutes",
              "targetMinutes",
              "source",
              "shiftType"
            ]
          },
          "workDayId": {
            "type": "string",
            "nullable": true
          },
          "effectiveSettings": {
            "type": "object",
            "properties": {
              "breakDeductionMode": {
                "type": "string",
                "enum": [
                  "none",
                  "minimum",
                  "fixed"
                ]
              },
              "breakThresholdMinutes": {
                "type": "number"
              },
              "breakThresholdBasis": {
                "type": "string",
                "enum": [
                  "work",
                  "span"
                ]
              },
              "minBreakMinutes": {
                "type": "number"
              },
              "paidCoffeeTotalMinutes": {
                "type": "number"
              },
              "paidCoffeeMaxCount": {
                "type": "number"
              },
              "flexWindowStartMinutes": {
                "type": "number",
                "nullable": true
              },
              "flexWindowEndMinutes": {
                "type": "number",
                "nullable": true
              },
              "dayFlexCapMinutes": {
                "type": "number",
                "nullable": true
              },
              "dayFlexFloorMinutes": {
                "type": "number",
                "nullable": true
              },
              "dailyRegularBasis": {
                "type": "string",
                "enum": [
                  "target",
                  "fixed"
                ]
              },
              "dailyRegularFixedMinutes": {
                "type": "number",
                "nullable": true
              },
              "dailyOt50Minutes": {
                "type": "number",
                "nullable": true
              },
              "flexRoundingMinutes": {
                "type": "number"
              },
              "openPunchAutoClose": {
                "type": "string",
                "enum": [
                  "off",
                  "boundary",
                  "planned_end"
                ]
              },
              "punchRoundingMinutes": {
                "type": "number"
              },
              "punchGraceStartMinutes": {
                "type": "number"
              },
              "punchGraceEndMinutes": {
                "type": "number"
              },
              "trace": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              }
            },
            "required": [
              "breakDeductionMode",
              "breakThresholdMinutes",
              "breakThresholdBasis",
              "minBreakMinutes",
              "paidCoffeeTotalMinutes",
              "paidCoffeeMaxCount",
              "flexWindowStartMinutes",
              "flexWindowEndMinutes",
              "dayFlexCapMinutes",
              "dayFlexFloorMinutes",
              "dailyRegularBasis",
              "dailyRegularFixedMinutes",
              "dailyOt50Minutes",
              "flexRoundingMinutes",
              "openPunchAutoClose",
              "punchRoundingMinutes",
              "punchGraceStartMinutes",
              "punchGraceEndMinutes",
              "trace"
            ]
          },
          "statutoryBasis": {
            "type": "boolean"
          },
          "worktimeRegime": {
            "type": "string",
            "enum": [
              "standard",
              "flexwork",
              "period"
            ]
          },
          "emergencyMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "openCorrectionRequest": {
            "type": "object",
            "properties": {
              "reason": {
                "type": "string"
              },
              "by": {
                "type": "string"
              },
              "requestedAt": {
                "type": "string"
              }
            },
            "required": [
              "reason",
              "by",
              "requestedAt"
            ],
            "default": null,
            "nullable": true
          },
          "shiftTypeOverride": {
            "type": "object",
            "properties": {
              "shiftTypeId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              }
            },
            "required": [
              "shiftTypeId"
            ],
            "default": null,
            "nullable": true
          },
          "shiftTypeOverrideInvalid": {
            "type": "boolean"
          },
          "shiftTypeOverrideMode": {
            "type": "string",
            "enum": [
              "off",
              "manager",
              "employee"
            ]
          },
          "resolutionWindows": {
            "default": [],
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "shiftTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "shortCode": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "priority": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "shiftTypeId",
                "nameFi",
                "nameSv",
                "nameEn",
                "shortCode",
                "color",
                "startMinutes",
                "endMinutes",
                "priority"
              ]
            }
          }
        },
        "required": [
          "workDate",
          "status",
          "startMinutes",
          "endMinutes",
          "breakMinutes",
          "workMinutes",
          "creditedMinutes",
          "targetMinutes",
          "balanceDeltaMinutes",
          "runningBalanceMinutes",
          "overtimeMinutes",
          "dayType",
          "sources",
          "deviations",
          "entries",
          "expectedSource",
          "workDayId"
        ]
      },
      "SetDayTypeDto": {
        "type": "object",
        "properties": {
          "dayTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        },
        "required": [
          "dayTypeId"
        ]
      },
      "WorkDayViewDto": {
        "type": "object",
        "properties": {
          "workDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "proposed",
              "draft",
              "confirmed",
              "approved",
              "exported"
            ]
          },
          "startMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1440,
            "nullable": true
          },
          "endMinutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2880,
            "nullable": true
          },
          "breakMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "breaks": {
            "default": [],
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "breakTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "paidMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "startMinutes",
                "endMinutes",
                "breakTypeId",
                "paidMinutes"
              ]
            }
          },
          "paidBreakMinutes": {
            "default": 0,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "workMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "creditedMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "targetMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "appliedCreditMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "uncountedMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "rawDeltaMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "balanceDeltaMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "attentionThresholdMinutes": {
            "default": 15,
            "type": "integer",
            "minimum": 0,
            "maximum": 480
          },
          "runningBalanceMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "overtimeMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "dayType": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]{1,49}$"
              },
              "nameFi": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "nameSv": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              },
              "nameEn": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
              }
            },
            "required": [
              "id",
              "code",
              "nameFi",
              "nameSv",
              "nameEn"
            ],
            "nullable": true
          },
          "absencePeriod": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "status": {
                "type": "string",
                "enum": [
                  "draft",
                  "submitted",
                  "approved",
                  "rejected",
                  "cancelled",
                  "withdrawn"
                ]
              },
              "workflowMode": {
                "type": "string",
                "enum": [
                  "request",
                  "notification",
                  "employer_assignment"
                ]
              },
              "nameFi": {
                "type": "string"
              },
              "nameSv": {
                "type": "string"
              },
              "nameEn": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "status",
              "workflowMode",
              "nameFi",
              "nameSv",
              "nameEn"
            ],
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "worktime-model",
                    "calendar-event",
                    "planned-shift",
                    "punch",
                    "learned-baseline"
                  ]
                },
                "versionId": {
                  "type": "string"
                },
                "eventId": {
                  "type": "string"
                },
                "shiftId": {
                  "type": "string"
                },
                "punchSessionId": {
                  "type": "string"
                },
                "weekday": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 7
                }
              },
              "required": [
                "type"
              ]
            }
          },
          "deviations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "overlong-day",
                    "short-day",
                    "missing-break",
                    "missing-second-break",
                    "fragmented-break",
                    "break-at-day-edge",
                    "flex-limit-exceeded",
                    "outside-flex-window",
                    "outside-allowed-window",
                    "work-on-day-off",
                    "entry-over-max-duration",
                    "insufficient-daily-rest",
                    "insufficient-weekly-rest"
                  ]
                },
                "deltaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "advisory",
                    "info"
                  ]
                }
              },
              "required": [
                "type",
                "deltaMinutes"
              ]
            }
          },
          "overtimeDisposition": {
            "default": "flex",
            "type": "string",
            "enum": [
              "flex",
              "payout",
              "ignore",
              "bank"
            ]
          },
          "bankAccountTypeId": {
            "type": "string",
            "default": null,
            "nullable": true
          },
          "entries": {
            "default": [],
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "entryTypeId": {
                  "type": "string"
                },
                "entryTypeCode": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,49}$"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2879,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "durationMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "default": null,
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "billable": {
                  "type": "boolean"
                },
                "billingBaseMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "default": null,
                  "nullable": true
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueCode": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string"
                      },
                      "weightBp": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueCode",
                      "valueName",
                      "weightBp"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "entryTypeId",
                "entryTypeCode",
                "startMinutes",
                "endMinutes",
                "note",
                "billable",
                "allocations"
              ]
            }
          },
          "proposedEntries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "entryTypeId": {
                  "type": "string"
                },
                "billable": {
                  "type": "boolean"
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueCode": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string"
                      },
                      "weightBp": {
                        "default": 10000,
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "calendar",
                          "geofence",
                          "task",
                          "baseline",
                          "default"
                        ]
                      },
                      "confidence": {
                        "type": "string",
                        "enum": [
                          "high",
                          "medium",
                          "low"
                        ]
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueCode",
                      "valueName",
                      "source",
                      "confidence"
                    ]
                  }
                },
                "confidence": {
                  "type": "string",
                  "enum": [
                    "high",
                    "medium",
                    "low"
                  ]
                }
              },
              "required": [
                "startMinutes",
                "endMinutes",
                "entryTypeId",
                "billable",
                "allocations",
                "confidence"
              ]
            }
          },
          "expectedSource": {
            "type": "string",
            "nullable": true
          },
          "expectedWindow": {
            "type": "object",
            "properties": {
              "startMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1440
              },
              "endMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1440
              },
              "breakMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "startMinutes",
              "endMinutes",
              "breakMinutes"
            ],
            "nullable": true
          },
          "proposalDismissed": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string",
            "default": null,
            "nullable": true
          },
          "returnReason": {
            "type": "string",
            "nullable": true
          },
          "confirmationOptional": {
            "type": "boolean"
          },
          "confirmedOnBehalf": {
            "type": "boolean"
          },
          "autoConfirmed": {
            "type": "boolean"
          },
          "confidence": {
            "type": "object",
            "properties": {
              "level": {
                "type": "string",
                "enum": [
                  "high",
                  "medium",
                  "low"
                ]
              },
              "reasons": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "level",
              "reasons"
            ]
          },
          "supplements": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "supplementTypeId": {
                  "type": "string"
                },
                "supplementTypeCode": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,49}$"
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "valueKind": {
                  "type": "string",
                  "enum": [
                    "flag",
                    "count",
                    "hours",
                    "amount"
                  ]
                },
                "unit": {
                  "type": "string",
                  "enum": [
                    "hours",
                    "pieces",
                    "days",
                    "decimal"
                  ]
                },
                "exportMode": {
                  "type": "string",
                  "enum": [
                    "passthrough",
                    "tesOnly"
                  ]
                },
                "quantity": {
                  "type": "number"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "comment": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "supplementTypeId",
                "supplementTypeCode",
                "nameFi",
                "nameSv",
                "nameEn",
                "valueKind",
                "unit",
                "exportMode",
                "quantity",
                "startMinutes",
                "endMinutes",
                "comment"
              ]
            }
          },
          "standby": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "periodId": {
                  "type": "string"
                },
                "standbyType": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{1,49}$"
                    },
                    "nameFi": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameSv": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameEn": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "worktimeFraction": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn",
                    "worktimeFraction"
                  ]
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 1440
                }
              },
              "required": [
                "periodId",
                "standbyType",
                "startMinutes",
                "endMinutes"
              ]
            }
          },
          "governingShiftType": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "nameFi": {
                "type": "string"
              },
              "nameSv": {
                "type": "string"
              },
              "nameEn": {
                "type": "string"
              },
              "shortCode": {
                "type": "string"
              },
              "color": {
                "type": "string"
              },
              "source": {
                "type": "string",
                "enum": [
                  "plan",
                  "walk-up",
                  "rule",
                  "model-default",
                  "override"
                ]
              }
            },
            "required": [
              "nameFi",
              "nameSv",
              "nameEn",
              "shortCode",
              "color"
            ]
          },
          "plannedShift": {
            "type": "object",
            "properties": {
              "startMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "endMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "breakMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "targetMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "source": {
                "type": "string",
                "enum": [
                  "person-shift",
                  "group-shift"
                ]
              },
              "shiftType": {
                "type": "object",
                "properties": {
                  "nameFi": {
                    "type": "string"
                  },
                  "nameSv": {
                    "type": "string"
                  },
                  "nameEn": {
                    "type": "string"
                  },
                  "shortCode": {
                    "type": "string"
                  },
                  "color": {
                    "type": "string"
                  }
                },
                "required": [
                  "nameFi",
                  "nameSv",
                  "nameEn",
                  "shortCode",
                  "color"
                ],
                "nullable": true
              }
            },
            "required": [
              "startMinutes",
              "endMinutes",
              "breakMinutes",
              "targetMinutes",
              "source",
              "shiftType"
            ]
          }
        },
        "required": [
          "workDate",
          "status",
          "startMinutes",
          "endMinutes",
          "breakMinutes",
          "workMinutes",
          "creditedMinutes",
          "targetMinutes",
          "balanceDeltaMinutes",
          "runningBalanceMinutes",
          "overtimeMinutes",
          "dayType",
          "sources",
          "deviations",
          "expectedSource"
        ]
      },
      "SetWorkEntriesDto": {
        "type": "object",
        "properties": {
          "entries": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "entryTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2879
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "durationMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 1440
                },
                "note": {
                  "type": "string",
                  "maxLength": 200
                },
                "billable": {
                  "default": false,
                  "type": "boolean"
                },
                "billingBaseMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "allocations": {
                  "default": [],
                  "maxItems": 10,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "valueId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "weightBp": {
                        "default": 10000,
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10000
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId"
                    ]
                  }
                },
                "taskId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                }
              },
              "required": [
                "entryTypeId"
              ]
            }
          },
          "breaks": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2880
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "breakTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                }
              },
              "required": [
                "startMinutes",
                "endMinutes"
              ]
            }
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "entries"
        ]
      },
      "BalanceResponseDto": {
        "type": "object",
        "properties": {
          "totalMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "runningMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "todayMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "isProvisional": {
            "type": "boolean"
          },
          "asOf": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "unrecordedDayCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "oldestUnrecordedDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "flexStatus": {
            "type": "string",
            "enum": [
              "within-limits",
              "over-max",
              "under-min"
            ]
          },
          "flexMinMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "flexMaxMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "trend": {
            "type": "object",
            "properties": {
              "direction": {
                "type": "string",
                "enum": [
                  "toward-max",
                  "toward-min",
                  "flat"
                ]
              },
              "ratePerDayMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "daysToCap": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              }
            },
            "required": [
              "direction",
              "ratePerDayMinutes",
              "daysToCap"
            ]
          }
        },
        "required": [
          "totalMinutes",
          "runningMinutes",
          "todayMinutes",
          "isProvisional",
          "asOf",
          "unrecordedDayCount",
          "oldestUnrecordedDate",
          "flexStatus",
          "flexMinMinutes",
          "flexMaxMinutes"
        ]
      },
      "StaffGroupListResponseDto": {
        "type": "object",
        "properties": {
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "active": {
                  "type": "boolean"
                },
                "criteria": {
                  "type": "object",
                  "properties": {
                    "payType": {
                      "type": "string",
                      "enum": [
                        "monthly",
                        "hourly"
                      ]
                    },
                    "employmentType": {
                      "type": "string",
                      "enum": [
                        "permanent",
                        "fixed_term"
                      ]
                    },
                    "worktimeModelIds": {
                      "minItems": 1,
                      "maxItems": 200,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    },
                    "planningUnitIds": {
                      "minItems": 1,
                      "maxItems": 200,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    },
                    "employerIds": {
                      "minItems": 1,
                      "maxItems": 200,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    },
                    "roles": {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "employee",
                          "manager",
                          "admin",
                          "payroll",
                          "hr"
                        ]
                      }
                    },
                    "includeMembershipIds": {
                      "minItems": 1,
                      "maxItems": 2000,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    },
                    "excludeMembershipIds": {
                      "minItems": 1,
                      "maxItems": 2000,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    }
                  },
                  "additionalProperties": false
                },
                "memberCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "sortOrder",
                "active",
                "criteria",
                "memberCount",
                "createdAt",
                "updatedAt"
              ]
            }
          }
        },
        "required": [
          "groups"
        ]
      },
      "ConfirmWorkDayDto": {
        "type": "object",
        "properties": {
          "startMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1440
          },
          "endMinutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2880
          },
          "breakMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "overtimeDisposition": {
            "type": "string",
            "enum": [
              "flex",
              "payout",
              "ignore",
              "bank"
            ]
          },
          "bankAccountTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        }
      },
      "ConfirmWorkDayResponseDto": {
        "type": "object",
        "properties": {
          "workDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "proposed",
              "draft",
              "confirmed",
              "approved",
              "exported"
            ]
          }
        },
        "required": [
          "workDate",
          "status"
        ]
      },
      "WorkDayActionResponseDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "proposed",
              "draft",
              "confirmed",
              "approved",
              "exported"
            ]
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "params": {
                  "default": {},
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "code"
              ]
            }
          }
        },
        "required": [
          "status"
        ]
      },
      "RangeActionDto": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          }
        },
        "required": [
          "from",
          "to"
        ]
      },
      "RangeActionResponseDto": {
        "type": "object",
        "properties": {
          "actedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skippedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "code": {
                  "type": "string"
                }
              },
              "required": [
                "workDate",
                "code"
              ]
            }
          }
        },
        "required": [
          "actedCount",
          "skippedCount",
          "skipped"
        ]
      },
      "ApproveWorkDayDto": {
        "type": "object",
        "properties": {
          "overtimeDisposition": {
            "type": "string",
            "enum": [
              "flex",
              "payout",
              "ignore",
              "bank"
            ]
          },
          "bankAccountTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        },
        "default": {}
      },
      "ApproveWorkDaysBatchDto": {
        "type": "object",
        "properties": {
          "items": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDayId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "overtimeDisposition": {
                  "type": "string",
                  "enum": [
                    "flex",
                    "payout",
                    "ignore",
                    "bank"
                  ]
                },
                "bankAccountTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                }
              },
              "required": [
                "workDayId"
              ]
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "ApproveWorkDaysBatchResponseDto": {
        "type": "object",
        "properties": {
          "actedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skippedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDayId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "code": {
                  "type": "string"
                }
              },
              "required": [
                "workDayId",
                "code"
              ]
            }
          }
        },
        "required": [
          "actedCount",
          "skippedCount",
          "skipped"
        ]
      },
      "ReturnWorkDaysBatchDto": {
        "type": "object",
        "properties": {
          "workDayIds": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500
          }
        },
        "required": [
          "workDayIds",
          "reason"
        ]
      },
      "ReturnWorkDaysBatchResponseDto": {
        "type": "object",
        "properties": {
          "actedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skippedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDayId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "code": {
                  "type": "string"
                }
              },
              "required": [
                "workDayId",
                "code"
              ]
            }
          }
        },
        "required": [
          "actedCount",
          "skippedCount",
          "skipped"
        ]
      },
      "ReturnWorkDayDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500
          }
        },
        "required": [
          "reason"
        ]
      },
      "WebhookEndpointListResponseDto": {
        "type": "object",
        "properties": {
          "endpoints": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "format": {
                  "type": "string",
                  "enum": [
                    "json",
                    "slack",
                    "teams"
                  ]
                },
                "events": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "quote.decided",
                      "batch.created",
                      "status_update.posted",
                      "deal.won",
                      "lead.created",
                      "workday.approved",
                      "export_batch.created",
                      "export_batch.delivered",
                      "export_batch.delivery_failed",
                      "absence.submitted",
                      "absence.decided",
                      "shift.published",
                      "invoice.issued",
                      "invoice.credited",
                      "invoice.dispatched",
                      "invoice.delivered",
                      "invoice.delivery_failed",
                      "payment.recorded",
                      "payment.allocated",
                      "payment.imported",
                      "invoice.overdue",
                      "invoice.drafts_ready",
                      "recurring_plan.run_completed",
                      "batch.delivered",
                      "workday.confirmed",
                      "workday.returned",
                      "workday.corrected",
                      "workday.unapproved",
                      "absence.cancelled",
                      "absence.certificate_provided",
                      "shift.changed",
                      "open_shift.claimed",
                      "open_shift.claim_decided",
                      "shift_swap.proposed",
                      "shift_swap.decided",
                      "export_batch.cancelled",
                      "payroll_period.locked",
                      "payroll_period.lock_lifted",
                      "member.created",
                      "member.invited",
                      "member.deactivated",
                      "employment.terminated",
                      "task.created",
                      "task.status_changed",
                      "task.approval_responded",
                      "quote.sent",
                      "quote.accepted",
                      "deal.lost",
                      "deal.stage_changed",
                      "lead.converted",
                      "intake.received",
                      "change_order.approved",
                      "project.created",
                      "project.closed",
                      "contact.anonymized",
                      "lead.anonymized",
                      "invoice.paid",
                      "customer.created",
                      "customer.updated",
                      "project.updated",
                      "member.updated",
                      "shift.unpublished"
                    ]
                  }
                },
                "locale": {
                  "type": "string",
                  "enum": [
                    "fi",
                    "sv",
                    "en"
                  ]
                },
                "hasSecret": {
                  "type": "boolean"
                },
                "active": {
                  "type": "boolean"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                }
              },
              "required": [
                "id",
                "url",
                "format",
                "events",
                "locale",
                "hasSecret",
                "active",
                "createdAt"
              ]
            }
          }
        },
        "required": [
          "endpoints"
        ]
      },
      "CreateWebhookEndpointDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 500,
            "format": "uri"
          },
          "format": {
            "default": "json",
            "type": "string",
            "enum": [
              "json",
              "slack",
              "teams"
            ]
          },
          "events": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "quote.decided",
                "batch.created",
                "status_update.posted",
                "deal.won",
                "lead.created",
                "workday.approved",
                "export_batch.created",
                "export_batch.delivered",
                "export_batch.delivery_failed",
                "absence.submitted",
                "absence.decided",
                "shift.published",
                "invoice.issued",
                "invoice.credited",
                "invoice.dispatched",
                "invoice.delivered",
                "invoice.delivery_failed",
                "payment.recorded",
                "payment.allocated",
                "payment.imported",
                "invoice.overdue",
                "invoice.drafts_ready",
                "recurring_plan.run_completed",
                "batch.delivered",
                "workday.confirmed",
                "workday.returned",
                "workday.corrected",
                "workday.unapproved",
                "absence.cancelled",
                "absence.certificate_provided",
                "shift.changed",
                "open_shift.claimed",
                "open_shift.claim_decided",
                "shift_swap.proposed",
                "shift_swap.decided",
                "export_batch.cancelled",
                "payroll_period.locked",
                "payroll_period.lock_lifted",
                "member.created",
                "member.invited",
                "member.deactivated",
                "employment.terminated",
                "task.created",
                "task.status_changed",
                "task.approval_responded",
                "quote.sent",
                "quote.accepted",
                "deal.lost",
                "deal.stage_changed",
                "lead.converted",
                "intake.received",
                "change_order.approved",
                "project.created",
                "project.closed",
                "contact.anonymized",
                "lead.anonymized",
                "invoice.paid",
                "customer.created",
                "customer.updated",
                "project.updated",
                "member.updated",
                "shift.unpublished"
              ]
            }
          },
          "locale": {
            "default": "fi",
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          }
        },
        "required": [
          "url",
          "events"
        ]
      },
      "CreateWebhookEndpointResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "secret": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "secret"
        ]
      },
      "UpdateWebhookEndpointDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 500,
            "format": "uri"
          },
          "events": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "quote.decided",
                "batch.created",
                "status_update.posted",
                "deal.won",
                "lead.created",
                "workday.approved",
                "export_batch.created",
                "export_batch.delivered",
                "export_batch.delivery_failed",
                "absence.submitted",
                "absence.decided",
                "shift.published",
                "invoice.issued",
                "invoice.credited",
                "invoice.dispatched",
                "invoice.delivered",
                "invoice.delivery_failed",
                "payment.recorded",
                "payment.allocated",
                "payment.imported",
                "invoice.overdue",
                "invoice.drafts_ready",
                "recurring_plan.run_completed",
                "batch.delivered",
                "workday.confirmed",
                "workday.returned",
                "workday.corrected",
                "workday.unapproved",
                "absence.cancelled",
                "absence.certificate_provided",
                "shift.changed",
                "open_shift.claimed",
                "open_shift.claim_decided",
                "shift_swap.proposed",
                "shift_swap.decided",
                "export_batch.cancelled",
                "payroll_period.locked",
                "payroll_period.lock_lifted",
                "member.created",
                "member.invited",
                "member.deactivated",
                "employment.terminated",
                "task.created",
                "task.status_changed",
                "task.approval_responded",
                "quote.sent",
                "quote.accepted",
                "deal.lost",
                "deal.stage_changed",
                "lead.converted",
                "intake.received",
                "change_order.approved",
                "project.created",
                "project.closed",
                "contact.anonymized",
                "lead.anonymized",
                "invoice.paid",
                "customer.created",
                "customer.updated",
                "project.updated",
                "member.updated",
                "shift.unpublished"
              ]
            }
          },
          "locale": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "active": {
            "type": "boolean"
          }
        }
      },
      "WebhookOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "RotateWebhookSecretResponseDto": {
        "type": "object",
        "properties": {
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "secret"
        ]
      },
      "WebhookDeliveryPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "event": {
                  "type": "string"
                },
                "integrationEventId": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "delivered",
                    "failed",
                    "dead_letter"
                  ]
                },
                "attempts": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "lastError": {
                  "type": "string",
                  "nullable": true
                },
                "httpStatus": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "nextAttemptAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "deliveredAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "event",
                "integrationEventId",
                "status",
                "attempts",
                "lastError",
                "httpStatus",
                "nextAttemptAt",
                "createdAt",
                "deliveredAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "IntegrationEventPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "event": {
                  "type": "string",
                  "enum": [
                    "quote.decided",
                    "batch.created",
                    "status_update.posted",
                    "deal.won",
                    "lead.created",
                    "workday.approved",
                    "export_batch.created",
                    "export_batch.delivered",
                    "export_batch.delivery_failed",
                    "absence.submitted",
                    "absence.decided",
                    "shift.published",
                    "invoice.issued",
                    "invoice.credited",
                    "invoice.dispatched",
                    "invoice.delivered",
                    "invoice.delivery_failed",
                    "payment.recorded",
                    "payment.allocated",
                    "payment.imported",
                    "invoice.overdue",
                    "invoice.drafts_ready",
                    "recurring_plan.run_completed",
                    "batch.delivered",
                    "workday.confirmed",
                    "workday.returned",
                    "workday.corrected",
                    "workday.unapproved",
                    "absence.cancelled",
                    "absence.certificate_provided",
                    "shift.changed",
                    "open_shift.claimed",
                    "open_shift.claim_decided",
                    "shift_swap.proposed",
                    "shift_swap.decided",
                    "export_batch.cancelled",
                    "payroll_period.locked",
                    "payroll_period.lock_lifted",
                    "member.created",
                    "member.invited",
                    "member.deactivated",
                    "employment.terminated",
                    "task.created",
                    "task.status_changed",
                    "task.approval_responded",
                    "quote.sent",
                    "quote.accepted",
                    "deal.lost",
                    "deal.stage_changed",
                    "lead.converted",
                    "intake.received",
                    "change_order.approved",
                    "project.created",
                    "project.closed",
                    "contact.anonymized",
                    "lead.anonymized",
                    "invoice.paid",
                    "customer.created",
                    "customer.updated",
                    "project.updated",
                    "member.updated",
                    "shift.unpublished"
                  ]
                },
                "payload": {
                  "type": "object",
                  "additionalProperties": {}
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                }
              },
              "required": [
                "id",
                "event",
                "payload",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "WebhookEventCatalogResponseDto": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "event": {
                  "type": "string",
                  "enum": [
                    "quote.decided",
                    "batch.created",
                    "status_update.posted",
                    "deal.won",
                    "lead.created",
                    "workday.approved",
                    "export_batch.created",
                    "export_batch.delivered",
                    "export_batch.delivery_failed",
                    "absence.submitted",
                    "absence.decided",
                    "shift.published",
                    "invoice.issued",
                    "invoice.credited",
                    "invoice.dispatched",
                    "invoice.delivered",
                    "invoice.delivery_failed",
                    "payment.recorded",
                    "payment.allocated",
                    "payment.imported",
                    "invoice.overdue",
                    "invoice.drafts_ready",
                    "recurring_plan.run_completed",
                    "batch.delivered",
                    "workday.confirmed",
                    "workday.returned",
                    "workday.corrected",
                    "workday.unapproved",
                    "absence.cancelled",
                    "absence.certificate_provided",
                    "shift.changed",
                    "open_shift.claimed",
                    "open_shift.claim_decided",
                    "shift_swap.proposed",
                    "shift_swap.decided",
                    "export_batch.cancelled",
                    "payroll_period.locked",
                    "payroll_period.lock_lifted",
                    "member.created",
                    "member.invited",
                    "member.deactivated",
                    "employment.terminated",
                    "task.created",
                    "task.status_changed",
                    "task.approval_responded",
                    "quote.sent",
                    "quote.accepted",
                    "deal.lost",
                    "deal.stage_changed",
                    "lead.converted",
                    "intake.received",
                    "change_order.approved",
                    "project.created",
                    "project.closed",
                    "contact.anonymized",
                    "lead.anonymized",
                    "invoice.paid",
                    "customer.created",
                    "customer.updated",
                    "project.updated",
                    "member.updated",
                    "shift.unpublished"
                  ]
                },
                "capabilities": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "payloadSchema": {
                  "type": "object",
                  "additionalProperties": {}
                }
              },
              "required": [
                "event",
                "capabilities",
                "payloadSchema"
              ]
            }
          }
        },
        "required": [
          "events"
        ]
      },
      "MeEntitlementsResponseDto": {
        "type": "object",
        "properties": {
          "modules": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "shift_planning",
                "travel_expense",
                "hr",
                "project_management",
                "crm"
              ]
            }
          },
          "tenantModules": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "shift_planning",
                "travel_expense",
                "hr",
                "project_management",
                "crm"
              ]
            }
          },
          "activatedModules": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "shift_planning",
                "travel_expense",
                "hr",
                "project_management",
                "crm"
              ]
            }
          },
          "tenantFeatures": {
            "type": "object",
            "properties": {
              "announcementsEnabled": {
                "type": "boolean"
              },
              "leaveAllowAdvance": {
                "type": "boolean"
              },
              "supplementsEnabled": {
                "type": "boolean"
              },
              "presenceBoardEnabled": {
                "type": "boolean"
              },
              "punchDevicesEnabled": {
                "type": "boolean"
              },
              "punchClockEnabled": {
                "type": "boolean"
              },
              "punchSitesEnabled": {
                "type": "boolean"
              },
              "automationEnabled": {
                "type": "boolean"
              },
              "autonomousSchedulingEnabled": {
                "type": "boolean"
              },
              "demandForecastEnabled": {
                "type": "boolean"
              },
              "rotationsEnabled": {
                "type": "boolean"
              },
              "standbyEnabled": {
                "type": "boolean"
              },
              "shiftMessagesEnabled": {
                "type": "boolean"
              },
              "openShiftsEnabled": {
                "type": "boolean"
              },
              "openShiftsCrossUnit": {
                "type": "boolean"
              },
              "shiftSwapsEnabled": {
                "type": "boolean"
              },
              "drivingTimeEnabled": {
                "type": "boolean"
              },
              "billingBaseEnabled": {
                "type": "boolean"
              },
              "entryBillableEnabled": {
                "type": "boolean"
              },
              "calendarSyncEnabled": {
                "type": "boolean"
              },
              "calendarFeedEnabled": {
                "type": "boolean"
              },
              "mileageEnabled": {
                "type": "boolean"
              },
              "perDiemEnabled": {
                "type": "boolean"
              },
              "foreignTravelEnabled": {
                "type": "boolean"
              },
              "travelExportEnabled": {
                "type": "boolean"
              },
              "expenseBillingEnabled": {
                "type": "boolean"
              },
              "receiptRequiredEnabled": {
                "type": "boolean"
              },
              "travelTwoStepApprovalEnabled": {
                "type": "boolean"
              },
              "workplaceClassificationEnabled": {
                "type": "boolean"
              },
              "tasksEnabled": {
                "type": "boolean"
              },
              "projectTimelineEnabled": {
                "type": "boolean"
              },
              "projectWorkloadEnabled": {
                "type": "boolean"
              },
              "projectQuotesEnabled": {
                "type": "boolean"
              },
              "projectEconomyEnabled": {
                "type": "boolean"
              },
              "projectBillingEnabled": {
                "type": "boolean"
              },
              "projectIntakeEnabled": {
                "type": "boolean"
              },
              "crmLeadsEnabled": {
                "type": "boolean"
              },
              "crmAutomationsEnabled": {
                "type": "boolean"
              },
              "crmEmailDropboxEnabled": {
                "type": "boolean"
              },
              "crmMailboxSyncEnabled": {
                "type": "boolean"
              },
              "skillSelfAssessmentEnabled": {
                "type": "boolean"
              },
              "hrRecruitingEnabled": {
                "type": "boolean"
              },
              "hrDevelopmentEnabled": {
                "type": "boolean"
              },
              "hrTrainingEnabled": {
                "type": "boolean"
              },
              "hrSafetyEnabled": {
                "type": "boolean"
              },
              "hrWhistleblowingEnabled": {
                "type": "boolean"
              },
              "hrServiceRequestsEnabled": {
                "type": "boolean"
              },
              "pulseEnabled": {
                "type": "boolean"
              },
              "managerCanRecordSkills": {
                "type": "boolean"
              },
              "managerCanAddCandidates": {
                "type": "boolean"
              },
              "managerCanReadTerms": {
                "type": "boolean"
              },
              "managerActOnBehalf": {
                "type": "boolean"
              },
              "managerProjectsAccess": {
                "type": "boolean"
              },
              "managerCrmAccess": {
                "type": "boolean"
              }
            },
            "required": [
              "announcementsEnabled",
              "leaveAllowAdvance",
              "supplementsEnabled",
              "presenceBoardEnabled",
              "punchDevicesEnabled",
              "punchClockEnabled",
              "punchSitesEnabled",
              "automationEnabled",
              "autonomousSchedulingEnabled",
              "demandForecastEnabled",
              "rotationsEnabled",
              "standbyEnabled",
              "shiftMessagesEnabled",
              "openShiftsEnabled",
              "openShiftsCrossUnit",
              "shiftSwapsEnabled",
              "drivingTimeEnabled",
              "billingBaseEnabled",
              "entryBillableEnabled",
              "calendarSyncEnabled",
              "calendarFeedEnabled",
              "mileageEnabled",
              "perDiemEnabled",
              "foreignTravelEnabled",
              "travelExportEnabled",
              "expenseBillingEnabled",
              "receiptRequiredEnabled",
              "travelTwoStepApprovalEnabled",
              "workplaceClassificationEnabled",
              "tasksEnabled",
              "projectTimelineEnabled",
              "projectWorkloadEnabled",
              "projectQuotesEnabled",
              "projectEconomyEnabled",
              "projectBillingEnabled",
              "projectIntakeEnabled",
              "crmLeadsEnabled",
              "crmAutomationsEnabled",
              "crmEmailDropboxEnabled",
              "crmMailboxSyncEnabled",
              "skillSelfAssessmentEnabled",
              "hrRecruitingEnabled",
              "hrDevelopmentEnabled",
              "hrTrainingEnabled",
              "hrSafetyEnabled",
              "hrWhistleblowingEnabled",
              "hrServiceRequestsEnabled",
              "pulseEnabled",
              "managerCanRecordSkills",
              "managerCanAddCandidates",
              "managerCanReadTerms",
              "managerActOnBehalf",
              "managerProjectsAccess",
              "managerCrmAccess"
            ]
          },
          "crmSeat": {
            "type": "boolean"
          },
          "worktimeMode": {
            "type": "string",
            "enum": [
              "office",
              "shift",
              "mixed"
            ]
          },
          "hasTes": {
            "type": "boolean"
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "worktime.supervise",
                "scheduling.plan",
                "scheduling.admin",
                "projects.manage",
                "projects.read",
                "crm.use",
                "crm.admin",
                "hr.manage",
                "hr.record",
                "payroll.run",
                "reports.team",
                "members.manage",
                "comms.announce",
                "integrations.manage",
                "org.admin"
              ]
            }
          }
        },
        "required": [
          "modules",
          "tenantModules",
          "activatedModules",
          "tenantFeatures",
          "crmSeat",
          "worktimeMode",
          "hasTes",
          "capabilities"
        ]
      },
      "TripIdResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "TripOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "TripListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "membershipId": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string"
                },
                "purpose": {
                  "type": "string"
                },
                "destination": {
                  "type": "string"
                },
                "scope": {
                  "type": "string",
                  "enum": [
                    "domestic",
                    "foreign"
                  ]
                },
                "startAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "endAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "submitted",
                    "reviewed",
                    "approved"
                  ]
                },
                "returnReason": {
                  "type": "string",
                  "nullable": true
                },
                "transportMode": {
                  "type": "string",
                  "enum": [
                    "own_car",
                    "company_car",
                    "public",
                    "plane",
                    "ship",
                    "other",
                    null
                  ],
                  "nullable": true
                },
                "valueName": {
                  "type": "string",
                  "nullable": true
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueName"
                    ]
                  }
                },
                "billable": {
                  "type": "boolean"
                },
                "taxFreeTotalCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "payableTotalCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "taxableTotalCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "reimbursableTotalCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "exportedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "submittedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "membershipId",
                "memberName",
                "purpose",
                "destination",
                "scope",
                "startAt",
                "endAt",
                "status",
                "returnReason",
                "transportMode",
                "valueName",
                "dimensionValueId",
                "allocations",
                "billable",
                "taxFreeTotalCents",
                "payableTotalCents",
                "taxableTotalCents",
                "reimbursableTotalCents",
                "exportedAt",
                "submittedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateTripDto": {
        "type": "object",
        "properties": {
          "purpose": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "destination": {
            "type": "string",
            "maxLength": 200
          },
          "scope": {
            "type": "string",
            "enum": [
              "domestic",
              "foreign"
            ]
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "countryCode": {
            "type": "string",
            "pattern": "^[A-Za-z]{2}(-[A-Za-z0-9]{2,3})?$"
          },
          "dimensionValueId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "allocations": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "billable": {
            "type": "boolean"
          },
          "reimbursable": {
            "type": "boolean"
          },
          "transportMode": {
            "type": "string",
            "enum": [
              "own_car",
              "company_car",
              "public",
              "plane",
              "ship",
              "other",
              null
            ],
            "nullable": true
          }
        },
        "required": [
          "purpose",
          "startAt",
          "endAt"
        ]
      },
      "TripViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "membershipId": {
            "type": "string"
          },
          "memberName": {
            "type": "string"
          },
          "purpose": {
            "type": "string"
          },
          "destination": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "enum": [
              "domestic",
              "foreign"
            ]
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "submitted",
              "reviewed",
              "approved"
            ]
          },
          "returnReason": {
            "type": "string",
            "nullable": true
          },
          "transportMode": {
            "type": "string",
            "enum": [
              "own_car",
              "company_car",
              "public",
              "plane",
              "ship",
              "other",
              null
            ],
            "nullable": true
          },
          "valueName": {
            "type": "string",
            "nullable": true
          },
          "dimensionValueId": {
            "type": "string",
            "nullable": true
          },
          "allocations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string"
                },
                "valueId": {
                  "type": "string"
                },
                "valueName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "dimensionId",
                "valueId",
                "valueName"
              ]
            }
          },
          "billable": {
            "type": "boolean"
          },
          "taxFreeTotalCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "payableTotalCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "taxableTotalCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "reimbursableTotalCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "exportedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "reimbursable": {
            "type": "boolean"
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "approvedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "returnedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "legs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "countryCode": {
                  "type": "string",
                  "pattern": "^[A-Za-z]{2}(-[A-Za-z0-9]{2,3})?$"
                },
                "startAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "aboard": {
                  "type": "boolean"
                }
              },
              "required": [
                "startAt"
              ]
            }
          },
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "dayIndex": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "windowStart": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "windowEnd": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "durationMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "countryCode": {
                  "type": "string"
                },
                "rateCountryCode": {
                  "type": "string"
                },
                "countryOverride": {
                  "type": "boolean"
                },
                "freeMeals": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2
                },
                "freeLodging": {
                  "type": "boolean"
                },
                "nightAllowanceClaimed": {
                  "type": "boolean"
                },
                "nightAllowanceEligible": {
                  "type": "boolean"
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueName"
                    ]
                  }
                },
                "effectiveAllocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueName"
                    ]
                  }
                },
                "billable": {
                  "type": "boolean"
                },
                "reimbursable": {
                  "type": "boolean"
                },
                "level": {
                  "type": "string",
                  "enum": [
                    "full",
                    "partial",
                    "none"
                  ]
                },
                "perDiemBaseCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "perDiemCapCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "mealReductionCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "nightAllowanceCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "perDiemPaidCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "nightAllowancePaidCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "dayIndex",
                "windowStart",
                "windowEnd",
                "durationMinutes",
                "countryCode",
                "rateCountryCode",
                "countryOverride",
                "freeMeals",
                "freeLodging",
                "nightAllowanceClaimed",
                "nightAllowanceEligible",
                "note",
                "dimensionValueId",
                "allocations",
                "effectiveAllocations",
                "billable",
                "reimbursable",
                "level",
                "perDiemBaseCents",
                "perDiemCapCents",
                "mealReductionCents",
                "nightAllowanceCents",
                "perDiemPaidCents",
                "nightAllowancePaidCents"
              ]
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "membershipId": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string"
                },
                "expenseDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "type": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "actual",
                        "unit_rate",
                        "tes"
                      ]
                    },
                    "unit": {
                      "type": "string",
                      "enum": [
                        "piece",
                        "km",
                        "day"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn",
                    "kind",
                    "unit"
                  ]
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "quantity": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "vatBreakdown": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "rateBps": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 10000
                      },
                      "grossCents": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      },
                      "vatCents": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "rateBps",
                      "grossCents",
                      "vatCents"
                    ]
                  },
                  "nullable": true
                },
                "paidBy": {
                  "type": "string",
                  "enum": [
                    "company",
                    "employee"
                  ]
                },
                "reimbursable": {
                  "type": "boolean"
                },
                "billable": {
                  "type": "boolean"
                },
                "billableAmountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "billingMode": {
                  "type": "string",
                  "enum": [
                    "billable_amount",
                    "cost",
                    "cost_multiplier",
                    "manual"
                  ]
                },
                "billingMultiplierPermille": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "valueName": {
                  "type": "string",
                  "nullable": true
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueName"
                    ]
                  }
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "submitted",
                    "reviewed",
                    "approved"
                  ]
                },
                "submittedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "returnReason": {
                  "type": "string",
                  "nullable": true
                },
                "tripId": {
                  "type": "string",
                  "nullable": true
                },
                "tripDayId": {
                  "type": "string",
                  "nullable": true
                },
                "maxTaxFreeCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "originalCurrency": {
                  "type": "string",
                  "nullable": true
                },
                "originalAmountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "mileage": {
                  "type": "object",
                  "properties": {
                    "kmHundredths": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "fromText": {
                      "type": "string",
                      "nullable": true
                    },
                    "toText": {
                      "type": "string",
                      "nullable": true
                    },
                    "roundTrip": {
                      "type": "boolean"
                    },
                    "additions": {
                      "type": "object",
                      "properties": {
                        "passengers": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9
                        },
                        "trailer": {
                          "type": "boolean"
                        },
                        "caravan": {
                          "type": "boolean"
                        },
                        "heavyLoad": {
                          "type": "boolean"
                        },
                        "machine": {
                          "type": "boolean"
                        },
                        "dog": {
                          "type": "boolean"
                        },
                        "forest": {
                          "type": "boolean"
                        }
                      },
                      "nullable": true
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "manual",
                        "route",
                        "odometer",
                        "gps"
                      ]
                    },
                    "route": {
                      "type": "object",
                      "properties": {
                        "fromPlace": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 160
                            },
                            "lat": {
                              "type": "number",
                              "minimum": -90,
                              "maximum": 90
                            },
                            "lon": {
                              "type": "number",
                              "minimum": -180,
                              "maximum": 180
                            }
                          },
                          "required": [
                            "text"
                          ]
                        },
                        "toPlace": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 160
                            },
                            "lat": {
                              "type": "number",
                              "minimum": -90,
                              "maximum": 90
                            },
                            "lon": {
                              "type": "number",
                              "minimum": -180,
                              "maximum": 180
                            }
                          },
                          "required": [
                            "text"
                          ]
                        },
                        "waypoints": {
                          "maxItems": 15,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 160
                              },
                              "lat": {
                                "type": "number",
                                "minimum": -90,
                                "maximum": 90
                              },
                              "lon": {
                                "type": "number",
                                "minimum": -180,
                                "maximum": 180
                              }
                            },
                            "required": [
                              "text"
                            ]
                          }
                        },
                        "computedKmHundredths": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "provider": {
                          "type": "string",
                          "maxLength": 40
                        },
                        "alternativeIndex": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "fromPlace",
                        "toPlace",
                        "computedKmHundredths"
                      ],
                      "nullable": true
                    },
                    "odometer": {
                      "type": "object",
                      "properties": {
                        "startKm": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "endKm": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "startKm",
                        "endKm"
                      ],
                      "nullable": true
                    },
                    "vehicleId": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "kmHundredths",
                    "fromText",
                    "toText",
                    "roundTrip",
                    "additions",
                    "source",
                    "route",
                    "odometer",
                    "vehicleId"
                  ],
                  "nullable": true
                },
                "policyFlags": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "over_limit",
                      "receipt_required",
                      "project_required",
                      "meal_allowance_with_per_diem",
                      "possible_duplicate"
                    ]
                  }
                },
                "hasReceipt": {
                  "type": "boolean"
                },
                "exportedAt": {
                  "type": "string",
                  "nullable": true
                },
                "policyMaxPerExpenseCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                }
              },
              "required": [
                "id",
                "membershipId",
                "memberName",
                "expenseDate",
                "type",
                "description",
                "quantity",
                "amountCents",
                "vatCents",
                "vatBreakdown",
                "paidBy",
                "reimbursable",
                "billable",
                "billableAmountCents",
                "dimensionValueId",
                "valueName",
                "allocations",
                "status",
                "submittedAt",
                "returnReason",
                "tripId",
                "tripDayId",
                "maxTaxFreeCents",
                "originalCurrency",
                "originalAmountCents",
                "mileage",
                "policyFlags",
                "hasReceipt",
                "exportedAt",
                "policyMaxPerExpenseCents"
              ]
            }
          }
        },
        "required": [
          "id",
          "membershipId",
          "memberName",
          "purpose",
          "destination",
          "scope",
          "startAt",
          "endAt",
          "status",
          "returnReason",
          "transportMode",
          "valueName",
          "dimensionValueId",
          "allocations",
          "billable",
          "taxFreeTotalCents",
          "payableTotalCents",
          "taxableTotalCents",
          "reimbursableTotalCents",
          "exportedAt",
          "submittedAt",
          "reimbursable",
          "reviewedAt",
          "approvedAt",
          "returnedAt",
          "legs",
          "days",
          "lines"
        ]
      },
      "UpdateTripDto": {
        "type": "object",
        "properties": {
          "purpose": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "destination": {
            "type": "string",
            "maxLength": 200
          },
          "scope": {
            "type": "string",
            "enum": [
              "domestic",
              "foreign"
            ]
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "countryCode": {
            "type": "string",
            "pattern": "^[A-Za-z]{2}(-[A-Za-z0-9]{2,3})?$"
          },
          "dimensionValueId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "allocations": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "billable": {
            "type": "boolean"
          },
          "reimbursable": {
            "type": "boolean"
          },
          "transportMode": {
            "type": "string",
            "enum": [
              "own_car",
              "company_car",
              "public",
              "plane",
              "ship",
              "other",
              null
            ],
            "nullable": true
          },
          "legs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "countryCode": {
                  "type": "string",
                  "pattern": "^[A-Za-z]{2}(-[A-Za-z0-9]{2,3})?$"
                },
                "startAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "aboard": {
                  "type": "boolean"
                }
              },
              "required": [
                "startAt"
              ]
            }
          }
        }
      },
      "UpdateTripResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "attributionPropagated": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "attributionLocked": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "ok",
          "attributionPropagated",
          "attributionLocked"
        ]
      },
      "UpdateTripDayDto": {
        "type": "object",
        "properties": {
          "countryCode": {
            "type": "string",
            "pattern": "^[A-Za-z]{2}(-[A-Za-z0-9]{2,3})?$",
            "nullable": true
          },
          "freeMeals": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2
          },
          "freeLodging": {
            "type": "boolean"
          },
          "nightAllowanceClaimed": {
            "type": "boolean"
          },
          "note": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          },
          "dimensionValueId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "allocations": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "billable": {
            "type": "boolean"
          },
          "reimbursable": {
            "type": "boolean"
          }
        }
      },
      "ReturnTripDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          }
        },
        "required": [
          "reason"
        ]
      },
      "ProjectListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "dimensionValueId": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "contactName": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "ownerName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "active",
                    "on_hold",
                    "closed"
                  ]
                },
                "billingModel": {
                  "type": "string",
                  "enum": [
                    "time_materials",
                    "fixed_price",
                    "non_billable",
                    "retainer"
                  ]
                },
                "defaultBillable": {
                  "type": "boolean"
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "budgetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetAmountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "billingRoundingMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "contractAmountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "retainerQuotaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "purchaseBillingMultiplierPermille": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "taskTimeTracking": {
                  "type": "string",
                  "enum": [
                    "off",
                    "optional",
                    "required"
                  ]
                },
                "memberTaskVisibility": {
                  "type": "string",
                  "enum": [
                    "assigned_only",
                    "project_members"
                  ]
                },
                "taskAutoArchiveDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "code",
                "name",
                "dimensionValueId",
                "customerId",
                "customerName",
                "contactId",
                "contactName",
                "ownerMembershipId",
                "ownerName",
                "status",
                "billingModel",
                "defaultBillable",
                "startDate",
                "endDate",
                "budgetMinutes",
                "budgetAmountCents",
                "billingRoundingMinutes",
                "contractAmountCents",
                "retainerQuotaMinutes",
                "taskTimeTracking",
                "memberTaskVisibility",
                "taskAutoArchiveDays",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "ProjectOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "ProjectReportResponseDto": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "includesCost": {
            "type": "boolean"
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "projectId": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "ownerName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "active",
                    "on_hold",
                    "closed"
                  ]
                },
                "billingModel": {
                  "type": "string",
                  "enum": [
                    "time_materials",
                    "fixed_price",
                    "non_billable",
                    "retainer"
                  ]
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "health": {
                  "type": "string",
                  "enum": [
                    "on_track",
                    "at_risk",
                    "over_budget",
                    "no_data"
                  ]
                },
                "minutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "billableMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "lifetimeMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "revenueBasis": {
                  "type": "string",
                  "enum": [
                    "worked",
                    "invoiced"
                  ]
                },
                "revenueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "contractValueCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "approvedChangeOrderCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "invoicedLifetimeCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "costCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "marginCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "marginPct": {
                  "type": "number",
                  "nullable": true
                },
                "expenseCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "expenseRevenueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "purchaseCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "purchaseRevenueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "unpricedBillableMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "uncostedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetAmountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetMinutesUsedPct": {
                  "type": "number",
                  "nullable": true
                },
                "budgetAmountUsedPct": {
                  "type": "number",
                  "nullable": true
                },
                "openTaskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "overdueTaskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "healthReasons": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "over_budget",
                      "past_end",
                      "near_budget",
                      "thin_margin",
                      "losing",
                      "tasks_overdue"
                    ]
                  }
                },
                "statusUpdate": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "rag": {
                      "type": "string",
                      "enum": [
                        "on_track",
                        "at_risk",
                        "off_track"
                      ]
                    },
                    "note": {
                      "type": "string"
                    },
                    "authorName": {
                      "type": "string",
                      "nullable": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                    }
                  },
                  "required": [
                    "id",
                    "rag",
                    "note",
                    "authorName",
                    "createdAt"
                  ],
                  "nullable": true
                },
                "situation": {
                  "type": "string",
                  "enum": [
                    "on_track",
                    "at_risk",
                    "off_track",
                    "none"
                  ]
                },
                "situationSource": {
                  "type": "string",
                  "enum": [
                    "update",
                    "computed"
                  ]
                }
              },
              "required": [
                "projectId",
                "code",
                "name",
                "customerId",
                "customerName",
                "ownerMembershipId",
                "ownerName",
                "status",
                "billingModel",
                "startDate",
                "endDate",
                "health",
                "minutes",
                "billableMinutes",
                "lifetimeMinutes",
                "revenueBasis",
                "revenueCents",
                "contractValueCents",
                "approvedChangeOrderCents",
                "invoicedLifetimeCents",
                "costCents",
                "marginCents",
                "marginPct",
                "expenseCostCents",
                "expenseRevenueCents",
                "purchaseCostCents",
                "purchaseRevenueCents",
                "unpricedBillableMinutes",
                "uncostedMinutes",
                "budgetMinutes",
                "budgetAmountCents",
                "budgetMinutesUsedPct",
                "budgetAmountUsedPct",
                "openTaskCount",
                "overdueTaskCount",
                "healthReasons",
                "statusUpdate",
                "situation",
                "situationSource"
              ]
            }
          },
          "totals": {
            "type": "object",
            "properties": {
              "minutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "billableMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "revenueCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "costCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "marginCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "marginPct": {
                "type": "number",
                "nullable": true
              }
            },
            "required": [
              "minutes",
              "billableMinutes",
              "revenueCents",
              "costCents",
              "marginCents",
              "marginPct"
            ]
          },
          "unassignedMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "tesCost": {
            "type": "object",
            "properties": {
              "periodLabourCostCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "flatLabourCostCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "unweightedComponents": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "periodLabourCostCents",
              "flatLabourCostCents",
              "unweightedComponents"
            ],
            "nullable": true
          }
        },
        "required": [
          "from",
          "to",
          "includesCost",
          "rows",
          "totals",
          "unassignedMinutes"
        ]
      },
      "CreateProjectDto": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "billingModel": {
            "default": "time_materials",
            "type": "string",
            "enum": [
              "time_materials",
              "fixed_price",
              "non_billable",
              "retainer"
            ]
          },
          "defaultBillable": {
            "default": true,
            "type": "boolean"
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "budgetMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "budgetAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "billingRoundingMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 480,
            "nullable": true
          },
          "contractAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "retainerQuotaMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "purchaseBillingMultiplierPermille": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000,
            "nullable": true
          },
          "template": {
            "type": "object",
            "properties": {
              "templateId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "roleAssignments": {
                "default": [],
                "maxItems": 50,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "roleKey": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 40
                    },
                    "membershipId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "roleKey",
                    "membershipId"
                  ]
                }
              }
            },
            "required": [
              "templateId"
            ]
          }
        },
        "required": [
          "code",
          "name"
        ]
      },
      "ProjectIdResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "UpdateProjectDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "active",
              "on_hold",
              "closed"
            ]
          },
          "billingModel": {
            "type": "string",
            "enum": [
              "time_materials",
              "fixed_price",
              "non_billable",
              "retainer"
            ]
          },
          "defaultBillable": {
            "type": "boolean"
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "budgetMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "budgetAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "billingRoundingMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 480,
            "nullable": true
          },
          "contractAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "retainerQuotaMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "purchaseBillingMultiplierPermille": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000,
            "nullable": true
          },
          "taskTimeTracking": {
            "type": "string",
            "enum": [
              "off",
              "optional",
              "required"
            ]
          },
          "memberTaskVisibility": {
            "type": "string",
            "enum": [
              "assigned_only",
              "project_members"
            ]
          },
          "taskAutoArchiveDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "nullable": true
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "ProjectStatusUpdateListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "rag": {
                  "type": "string",
                  "enum": [
                    "on_track",
                    "at_risk",
                    "off_track"
                  ]
                },
                "note": {
                  "type": "string"
                },
                "authorName": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                }
              },
              "required": [
                "id",
                "rag",
                "note",
                "authorName",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateProjectStatusUpdateDto": {
        "type": "object",
        "properties": {
          "rag": {
            "type": "string",
            "enum": [
              "on_track",
              "at_risk",
              "off_track"
            ]
          },
          "note": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          }
        },
        "required": [
          "rag",
          "note"
        ]
      },
      "ProjectStatusUpdateViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "rag": {
            "type": "string",
            "enum": [
              "on_track",
              "at_risk",
              "off_track"
            ]
          },
          "note": {
            "type": "string"
          },
          "authorName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          }
        },
        "required": [
          "id",
          "rag",
          "note",
          "authorName",
          "createdAt"
        ]
      },
      "ProjectInstallmentListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "title": {
                  "type": "string"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "milestoneId": {
                  "type": "string",
                  "nullable": true
                },
                "milestoneName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "ready",
                    "draft_invoice",
                    "invoiced"
                  ]
                },
                "readyAt": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceBatchId": {
                  "type": "string",
                  "nullable": true
                },
                "invoicedAt": {
                  "type": "string",
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "projectId",
                "sortOrder",
                "title",
                "amountCents",
                "dueDate",
                "milestoneId",
                "milestoneName",
                "status",
                "readyAt",
                "invoiceBatchId",
                "invoicedAt",
                "updatedAt"
              ]
            }
          },
          "contractAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "totalCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "invoicedCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "draftInvoiceCents": {
            "default": 0,
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "readyCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "items",
          "contractAmountCents",
          "totalCents",
          "invoicedCents",
          "readyCents"
        ]
      },
      "ProjectPurchaseListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "phaseId": {
                  "type": "string",
                  "nullable": true
                },
                "phaseName": {
                  "type": "string",
                  "nullable": true
                },
                "date": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "supplierName": {
                  "type": "string",
                  "nullable": true
                },
                "description": {
                  "type": "string"
                },
                "category": {
                  "type": "string",
                  "enum": [
                    "material",
                    "subcontracting",
                    "rental",
                    "other"
                  ]
                },
                "quantity": {
                  "type": "number"
                },
                "unit": {
                  "type": "string"
                },
                "unitCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "totalCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "billable": {
                  "type": "boolean"
                },
                "unitSellCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "totalSellCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "billingMode": {
                  "type": "string",
                  "enum": [
                    "billable_amount",
                    "cost",
                    "cost_multiplier",
                    "manual"
                  ]
                },
                "billingMultiplierPermille": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "approved"
                  ]
                },
                "approvedAt": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceBatchId": {
                  "type": "string",
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "projectId",
                "phaseId",
                "phaseName",
                "date",
                "supplierName",
                "description",
                "category",
                "quantity",
                "unit",
                "unitCostCents",
                "totalCostCents",
                "billable",
                "unitSellCents",
                "totalSellCents",
                "status",
                "approvedAt",
                "invoiceBatchId",
                "updatedAt"
              ]
            }
          },
          "totalCostCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "totalSellCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "invoicedSellCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "byCategory": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "enum": [
                    "material",
                    "subcontracting",
                    "rental",
                    "other"
                  ]
                },
                "costCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "sellCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "category",
                "costCents",
                "sellCents"
              ]
            }
          },
          "suppliers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "purchaseBillingMultiplierPermille": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          }
        },
        "required": [
          "items",
          "totalCostCents",
          "totalSellCents",
          "invoicedSellCents",
          "byCategory",
          "suppliers",
          "purchaseBillingMultiplierPermille"
        ]
      },
      "ProjectActivityResponseDto": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string"
          },
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "totalMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "billableMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "entries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workEntryId": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "memberName": {
                  "type": "string"
                },
                "valueId": {
                  "type": "string"
                },
                "valueName": {
                  "type": "string"
                },
                "minutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "billable": {
                  "type": "boolean"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "confirmed",
                    "approved",
                    "exported"
                  ]
                },
                "canReattribute": {
                  "type": "boolean"
                }
              },
              "required": [
                "workEntryId",
                "workDate",
                "memberName",
                "valueId",
                "valueName",
                "minutes",
                "billable",
                "status",
                "canReattribute"
              ]
            }
          },
          "truncated": {
            "type": "boolean"
          }
        },
        "required": [
          "projectId",
          "from",
          "to",
          "totalMinutes",
          "billableMinutes",
          "entries",
          "truncated"
        ]
      },
      "ProjectPhaseListResponseDto": {
        "type": "object",
        "properties": {
          "phases": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "planned",
                    "active",
                    "done"
                  ]
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "dimensionValueId": {
                  "type": "string"
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "budgetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetAmountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "actualMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "budgetMinutesUsedPct": {
                  "type": "number",
                  "nullable": true
                },
                "actualCostCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetAmountUsedPct": {
                  "type": "number",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "code",
                "name",
                "status",
                "sortOrder",
                "dimensionValueId",
                "startDate",
                "endDate",
                "budgetMinutes",
                "budgetAmountCents",
                "actualMinutes",
                "budgetMinutesUsedPct",
                "actualCostCents",
                "budgetAmountUsedPct"
              ]
            }
          }
        },
        "required": [
          "phases"
        ]
      },
      "CreateExportBatchDto": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "groupId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "force": {
            "type": "boolean"
          },
          "forceReason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "includeCarryover": {
            "type": "boolean"
          }
        },
        "required": [
          "from",
          "to"
        ]
      },
      "ExportBatchViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "periodStart": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "periodEnd": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "createdAt": {
            "type": "string"
          },
          "dayCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "groupId": {
            "type": "string",
            "nullable": true
          },
          "deliveries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "targetId": {
                  "type": "string"
                },
                "targetName": {
                  "type": "string"
                },
                "transport": {
                  "type": "string",
                  "enum": [
                    "download",
                    "http",
                    "sftp",
                    "netvisor"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "delivering",
                    "delivered",
                    "failed"
                  ]
                },
                "deliveredAt": {
                  "type": "string",
                  "nullable": true
                },
                "attempts": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "targetId",
                "targetName",
                "transport",
                "status",
                "deliveredAt",
                "attempts"
              ]
            }
          },
          "lastDeliveredAt": {
            "type": "string",
            "nullable": true
          },
          "canceledAt": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "periodStart",
          "periodEnd",
          "createdAt",
          "dayCount",
          "groupId",
          "deliveries",
          "lastDeliveredAt",
          "canceledAt"
        ]
      },
      "ExportPreflightResponseDto": {
        "type": "object",
        "properties": {
          "exportableDayCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "unmappedBuckets": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "activeTargetCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "targetCoverage": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "targetId": {
                  "type": "string"
                },
                "targetName": {
                  "type": "string"
                },
                "personCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "unmappedBuckets": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "identifierKind": {
                  "type": "string",
                  "enum": [
                    "email",
                    "employee_number",
                    "ssn"
                  ]
                },
                "missingIdentifierNames": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "targetId",
                "targetName",
                "personCount",
                "unmappedBuckets",
                "identifierKind",
                "missingIdentifierNames"
              ]
            }
          },
          "uncoveredPersonCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "unapprovedDayCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "draftDayCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "missingDayCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "incompleteMembers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "missingDayCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "draftDayCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "unapprovedDayCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "missingDayCount",
                "draftDayCount",
                "unapprovedDayCount"
              ]
            }
          },
          "incompleteMemberTotal": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "carryoverDayCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "params": {
                  "default": {},
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "code"
              ]
            }
          },
          "exceptions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string"
                },
                "ruleName": {
                  "type": "string"
                },
                "date": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              },
              "required": [
                "membershipId",
                "memberName",
                "ruleName",
                "date",
                "code",
                "message"
              ]
            }
          },
          "premiumBandConflicts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "bandCode": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "evening",
                    "night",
                    "saturday",
                    "sunday",
                    "other"
                  ]
                },
                "tesPayCodes": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "suppressedMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "dayCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "memberCount": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "bandCode",
                "kind",
                "tesPayCodes",
                "suppressedMinutes",
                "dayCount",
                "memberCount"
              ]
            }
          }
        },
        "required": [
          "exportableDayCount",
          "unmappedBuckets",
          "activeTargetCount",
          "targetCoverage",
          "uncoveredPersonCount",
          "unapprovedDayCount",
          "draftDayCount",
          "missingDayCount",
          "incompleteMembers",
          "incompleteMemberTotal",
          "carryoverDayCount",
          "exceptions"
        ]
      },
      "ExportBatchListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "periodStart": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "periodEnd": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "createdAt": {
                  "type": "string"
                },
                "dayCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "groupId": {
                  "type": "string",
                  "nullable": true
                },
                "deliveries": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "targetId": {
                        "type": "string"
                      },
                      "targetName": {
                        "type": "string"
                      },
                      "transport": {
                        "type": "string",
                        "enum": [
                          "download",
                          "http",
                          "sftp",
                          "netvisor"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "pending",
                          "delivering",
                          "delivered",
                          "failed"
                        ]
                      },
                      "deliveredAt": {
                        "type": "string",
                        "nullable": true
                      },
                      "attempts": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "targetId",
                      "targetName",
                      "transport",
                      "status",
                      "deliveredAt",
                      "attempts"
                    ]
                  }
                },
                "lastDeliveredAt": {
                  "type": "string",
                  "nullable": true
                },
                "canceledAt": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "periodStart",
                "periodEnd",
                "createdAt",
                "dayCount",
                "groupId",
                "deliveries",
                "lastDeliveredAt",
                "canceledAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CalculationRunResponseDto": {
        "type": "object",
        "properties": {
          "batchId": {
            "type": "string"
          },
          "calculationRunId": {
            "type": "string",
            "nullable": true
          },
          "engineVersion": {
            "type": "string",
            "nullable": true
          },
          "periodStart": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "periodEnd": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "createdAt": {
            "type": "string"
          },
          "persons": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "components": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "componentCode": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "enum": [
                          "base",
                          "additional",
                          "overtime",
                          "premium",
                          "absence",
                          "accrual",
                          "supplement",
                          "uncounted",
                          "work_equivalent"
                        ]
                      },
                      "rule": {
                        "type": "string",
                        "enum": [
                          "normal_work",
                          "additional_work",
                          "daily_overtime_50",
                          "daily_overtime_100",
                          "weekly_overtime_50",
                          "weekly_overtime_100",
                          "period_overtime_50",
                          "period_overtime_100",
                          "period_additional",
                          "period_uncompensated",
                          "sub_period_premium_100",
                          "sunday_work",
                          "holiday_work",
                          "holiday_compensation",
                          "premium_band",
                          "standby",
                          "day_absence",
                          "partial_absence",
                          "tes_time_band",
                          "tes_formula",
                          "supplement",
                          "clock_window_uncounted",
                          "type_cap_uncounted",
                          "type_cap_unpaid_first",
                          "worktime_fraction_uncounted",
                          "prep_work",
                          "wrap_work",
                          "balance_overflow_payout",
                          "balance_cut_payout",
                          "overtime_rounding"
                        ]
                      },
                      "totalMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "count": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "rateCents": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "mapped": {
                        "type": "boolean"
                      },
                      "payCode": {
                        "type": "string",
                        "nullable": true
                      },
                      "payCodeName": {
                        "type": "string",
                        "nullable": true
                      },
                      "nameFi": {
                        "type": "string",
                        "nullable": true
                      },
                      "nameSv": {
                        "type": "string",
                        "nullable": true
                      },
                      "nameEn": {
                        "type": "string",
                        "nullable": true
                      },
                      "contributions": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "workDate": {
                              "type": "string",
                              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                            },
                            "minutes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "grain": {
                              "type": "string",
                              "enum": [
                                "day",
                                "week",
                                "period"
                              ]
                            },
                            "inputs": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "number"
                              }
                            },
                            "allocation": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "dimensionCode": {
                                    "type": "string"
                                  },
                                  "valueCode": {
                                    "type": "string"
                                  },
                                  "valueName": {
                                    "type": "string"
                                  },
                                  "minutes": {
                                    "type": "integer",
                                    "minimum": -9007199254740991,
                                    "maximum": 9007199254740991
                                  }
                                },
                                "required": [
                                  "dimensionCode",
                                  "valueCode",
                                  "valueName",
                                  "minutes"
                                ]
                              }
                            }
                          },
                          "required": [
                            "workDate",
                            "minutes",
                            "grain",
                            "inputs",
                            "allocation"
                          ]
                        }
                      }
                    },
                    "required": [
                      "componentCode",
                      "kind",
                      "rule",
                      "totalMinutes",
                      "count",
                      "rateCents",
                      "mapped",
                      "payCode",
                      "payCodeName",
                      "nameFi",
                      "nameSv",
                      "nameEn",
                      "contributions"
                    ]
                  }
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "components"
              ]
            }
          }
        },
        "required": [
          "batchId",
          "calculationRunId",
          "engineVersion",
          "periodStart",
          "periodEnd",
          "createdAt",
          "persons"
        ]
      },
      "CancelExportBatchDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500
          }
        },
        "required": [
          "reason"
        ]
      },
      "CancelExportBatchResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "canceledAt": {
            "type": "string"
          },
          "reversedDayCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "id",
          "canceledAt",
          "reversedDayCount"
        ]
      },
      "WorkDayDetailRangeResponseDto": {
        "type": "object",
        "properties": {
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "proposed",
                    "draft",
                    "confirmed",
                    "approved",
                    "exported"
                  ]
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "breaks": {
                  "default": [],
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                        "nullable": true
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "breakTypeId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                        "nullable": true
                      },
                      "paidMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "id",
                      "startMinutes",
                      "endMinutes",
                      "breakTypeId",
                      "paidMinutes"
                    ]
                  }
                },
                "paidBreakMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "workMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "creditedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "appliedCreditMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "uncountedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "rawDeltaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "balanceDeltaMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "attentionThresholdMinutes": {
                  "default": 15,
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 480
                },
                "runningBalanceMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "overtimeMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "dayType": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{1,49}$"
                    },
                    "nameFi": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameSv": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "nameEn": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn"
                  ],
                  "nullable": true
                },
                "absencePeriod": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "draft",
                        "submitted",
                        "approved",
                        "rejected",
                        "cancelled",
                        "withdrawn"
                      ]
                    },
                    "workflowMode": {
                      "type": "string",
                      "enum": [
                        "request",
                        "notification",
                        "employer_assignment"
                      ]
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "status",
                    "workflowMode",
                    "nameFi",
                    "nameSv",
                    "nameEn"
                  ],
                  "nullable": true
                },
                "sources": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "worktime-model",
                          "calendar-event",
                          "planned-shift",
                          "punch",
                          "learned-baseline"
                        ]
                      },
                      "versionId": {
                        "type": "string"
                      },
                      "eventId": {
                        "type": "string"
                      },
                      "shiftId": {
                        "type": "string"
                      },
                      "punchSessionId": {
                        "type": "string"
                      },
                      "weekday": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 7
                      }
                    },
                    "required": [
                      "type"
                    ]
                  }
                },
                "deviations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "overlong-day",
                          "short-day",
                          "missing-break",
                          "missing-second-break",
                          "fragmented-break",
                          "break-at-day-edge",
                          "flex-limit-exceeded",
                          "outside-flex-window",
                          "outside-allowed-window",
                          "work-on-day-off",
                          "entry-over-max-duration",
                          "insufficient-daily-rest",
                          "insufficient-weekly-rest"
                        ]
                      },
                      "deltaMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "severity": {
                        "type": "string",
                        "enum": [
                          "advisory",
                          "info"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "deltaMinutes"
                    ]
                  }
                },
                "overtimeDisposition": {
                  "default": "flex",
                  "type": "string",
                  "enum": [
                    "flex",
                    "payout",
                    "ignore",
                    "bank"
                  ]
                },
                "bankAccountTypeId": {
                  "type": "string",
                  "default": null,
                  "nullable": true
                },
                "entries": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "entryTypeId": {
                        "type": "string"
                      },
                      "entryTypeCode": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{1,49}$"
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 2879,
                        "nullable": true
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880,
                        "nullable": true
                      },
                      "durationMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "note": {
                        "type": "string",
                        "nullable": true
                      },
                      "billable": {
                        "type": "boolean"
                      },
                      "billingBaseMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "allocations": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "dimensionId": {
                              "type": "string"
                            },
                            "valueId": {
                              "type": "string"
                            },
                            "valueCode": {
                              "type": "string"
                            },
                            "valueName": {
                              "type": "string"
                            },
                            "weightBp": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            }
                          },
                          "required": [
                            "dimensionId",
                            "valueId",
                            "valueCode",
                            "valueName",
                            "weightBp"
                          ]
                        }
                      }
                    },
                    "required": [
                      "id",
                      "entryTypeId",
                      "entryTypeCode",
                      "startMinutes",
                      "endMinutes",
                      "note",
                      "billable",
                      "allocations"
                    ]
                  }
                },
                "proposedEntries": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "entryTypeId": {
                        "type": "string"
                      },
                      "billable": {
                        "type": "boolean"
                      },
                      "allocations": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "dimensionId": {
                              "type": "string"
                            },
                            "valueId": {
                              "type": "string"
                            },
                            "valueCode": {
                              "type": "string"
                            },
                            "valueName": {
                              "type": "string"
                            },
                            "weightBp": {
                              "default": 10000,
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "source": {
                              "type": "string",
                              "enum": [
                                "calendar",
                                "geofence",
                                "task",
                                "baseline",
                                "default"
                              ]
                            },
                            "confidence": {
                              "type": "string",
                              "enum": [
                                "high",
                                "medium",
                                "low"
                              ]
                            }
                          },
                          "required": [
                            "dimensionId",
                            "valueId",
                            "valueCode",
                            "valueName",
                            "source",
                            "confidence"
                          ]
                        }
                      },
                      "confidence": {
                        "type": "string",
                        "enum": [
                          "high",
                          "medium",
                          "low"
                        ]
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "entryTypeId",
                      "billable",
                      "allocations",
                      "confidence"
                    ]
                  }
                },
                "expectedSource": {
                  "type": "string",
                  "nullable": true
                },
                "expectedWindow": {
                  "type": "object",
                  "properties": {
                    "startMinutes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 1440
                    },
                    "endMinutes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 1440
                    },
                    "breakMinutes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "startMinutes",
                    "endMinutes",
                    "breakMinutes"
                  ],
                  "nullable": true
                },
                "proposalDismissed": {
                  "type": "boolean"
                },
                "updatedAt": {
                  "type": "string",
                  "default": null,
                  "nullable": true
                },
                "returnReason": {
                  "type": "string",
                  "nullable": true
                },
                "confirmationOptional": {
                  "type": "boolean"
                },
                "confirmedOnBehalf": {
                  "type": "boolean"
                },
                "autoConfirmed": {
                  "type": "boolean"
                },
                "confidence": {
                  "type": "object",
                  "properties": {
                    "level": {
                      "type": "string",
                      "enum": [
                        "high",
                        "medium",
                        "low"
                      ]
                    },
                    "reasons": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "level",
                    "reasons"
                  ]
                },
                "supplements": {
                  "default": [],
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "supplementTypeId": {
                        "type": "string"
                      },
                      "supplementTypeCode": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{1,49}$"
                      },
                      "nameFi": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "nameSv": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "nameEn": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "valueKind": {
                        "type": "string",
                        "enum": [
                          "flag",
                          "count",
                          "hours",
                          "amount"
                        ]
                      },
                      "unit": {
                        "type": "string",
                        "enum": [
                          "hours",
                          "pieces",
                          "days",
                          "decimal"
                        ]
                      },
                      "exportMode": {
                        "type": "string",
                        "enum": [
                          "passthrough",
                          "tesOnly"
                        ]
                      },
                      "quantity": {
                        "type": "number"
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440,
                        "nullable": true
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440,
                        "nullable": true
                      },
                      "comment": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "supplementTypeId",
                      "supplementTypeCode",
                      "nameFi",
                      "nameSv",
                      "nameEn",
                      "valueKind",
                      "unit",
                      "exportMode",
                      "quantity",
                      "startMinutes",
                      "endMinutes",
                      "comment"
                    ]
                  }
                },
                "standby": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "periodId": {
                        "type": "string"
                      },
                      "standbyType": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string",
                            "pattern": "^[a-z][a-z0-9_]{1,49}$"
                          },
                          "nameFi": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          },
                          "nameSv": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          },
                          "nameEn": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                          },
                          "worktimeFraction": {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 1
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "nameFi",
                          "nameSv",
                          "nameEn",
                          "worktimeFraction"
                        ]
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 1440
                      }
                    },
                    "required": [
                      "periodId",
                      "standbyType",
                      "startMinutes",
                      "endMinutes"
                    ]
                  }
                },
                "governingShiftType": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    },
                    "shortCode": {
                      "type": "string"
                    },
                    "color": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "plan",
                        "walk-up",
                        "rule",
                        "model-default",
                        "override"
                      ]
                    }
                  },
                  "required": [
                    "nameFi",
                    "nameSv",
                    "nameEn",
                    "shortCode",
                    "color"
                  ]
                },
                "plannedShift": {
                  "type": "object",
                  "properties": {
                    "startMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    },
                    "endMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    },
                    "breakMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "targetMinutes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "person-shift",
                        "group-shift"
                      ]
                    },
                    "shiftType": {
                      "type": "object",
                      "properties": {
                        "nameFi": {
                          "type": "string"
                        },
                        "nameSv": {
                          "type": "string"
                        },
                        "nameEn": {
                          "type": "string"
                        },
                        "shortCode": {
                          "type": "string"
                        },
                        "color": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "nameFi",
                        "nameSv",
                        "nameEn",
                        "shortCode",
                        "color"
                      ],
                      "nullable": true
                    }
                  },
                  "required": [
                    "startMinutes",
                    "endMinutes",
                    "breakMinutes",
                    "targetMinutes",
                    "source",
                    "shiftType"
                  ]
                },
                "workDayId": {
                  "type": "string",
                  "nullable": true
                },
                "effectiveSettings": {
                  "type": "object",
                  "properties": {
                    "breakDeductionMode": {
                      "type": "string",
                      "enum": [
                        "none",
                        "minimum",
                        "fixed"
                      ]
                    },
                    "breakThresholdMinutes": {
                      "type": "number"
                    },
                    "breakThresholdBasis": {
                      "type": "string",
                      "enum": [
                        "work",
                        "span"
                      ]
                    },
                    "minBreakMinutes": {
                      "type": "number"
                    },
                    "paidCoffeeTotalMinutes": {
                      "type": "number"
                    },
                    "paidCoffeeMaxCount": {
                      "type": "number"
                    },
                    "flexWindowStartMinutes": {
                      "type": "number",
                      "nullable": true
                    },
                    "flexWindowEndMinutes": {
                      "type": "number",
                      "nullable": true
                    },
                    "dayFlexCapMinutes": {
                      "type": "number",
                      "nullable": true
                    },
                    "dayFlexFloorMinutes": {
                      "type": "number",
                      "nullable": true
                    },
                    "dailyRegularBasis": {
                      "type": "string",
                      "enum": [
                        "target",
                        "fixed"
                      ]
                    },
                    "dailyRegularFixedMinutes": {
                      "type": "number",
                      "nullable": true
                    },
                    "dailyOt50Minutes": {
                      "type": "number",
                      "nullable": true
                    },
                    "flexRoundingMinutes": {
                      "type": "number"
                    },
                    "openPunchAutoClose": {
                      "type": "string",
                      "enum": [
                        "off",
                        "boundary",
                        "planned_end"
                      ]
                    },
                    "punchRoundingMinutes": {
                      "type": "number"
                    },
                    "punchGraceStartMinutes": {
                      "type": "number"
                    },
                    "punchGraceEndMinutes": {
                      "type": "number"
                    },
                    "trace": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "breakDeductionMode",
                    "breakThresholdMinutes",
                    "breakThresholdBasis",
                    "minBreakMinutes",
                    "paidCoffeeTotalMinutes",
                    "paidCoffeeMaxCount",
                    "flexWindowStartMinutes",
                    "flexWindowEndMinutes",
                    "dayFlexCapMinutes",
                    "dayFlexFloorMinutes",
                    "dailyRegularBasis",
                    "dailyRegularFixedMinutes",
                    "dailyOt50Minutes",
                    "flexRoundingMinutes",
                    "openPunchAutoClose",
                    "punchRoundingMinutes",
                    "punchGraceStartMinutes",
                    "punchGraceEndMinutes",
                    "trace"
                  ]
                },
                "statutoryBasis": {
                  "type": "boolean"
                },
                "worktimeRegime": {
                  "type": "string",
                  "enum": [
                    "standard",
                    "flexwork",
                    "period"
                  ]
                },
                "emergencyMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "openCorrectionRequest": {
                  "type": "object",
                  "properties": {
                    "reason": {
                      "type": "string"
                    },
                    "by": {
                      "type": "string"
                    },
                    "requestedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "reason",
                    "by",
                    "requestedAt"
                  ],
                  "default": null,
                  "nullable": true
                },
                "shiftTypeOverride": {
                  "type": "object",
                  "properties": {
                    "shiftTypeId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "shiftTypeId"
                  ],
                  "default": null,
                  "nullable": true
                },
                "shiftTypeOverrideInvalid": {
                  "type": "boolean"
                },
                "shiftTypeOverrideMode": {
                  "type": "string",
                  "enum": [
                    "off",
                    "manager",
                    "employee"
                  ]
                },
                "resolutionWindows": {
                  "default": [],
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "shiftTypeId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "nameFi": {
                        "type": "string"
                      },
                      "nameSv": {
                        "type": "string"
                      },
                      "nameEn": {
                        "type": "string"
                      },
                      "shortCode": {
                        "type": "string"
                      },
                      "color": {
                        "type": "string"
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "priority": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "shiftTypeId",
                      "nameFi",
                      "nameSv",
                      "nameEn",
                      "shortCode",
                      "color",
                      "startMinutes",
                      "endMinutes",
                      "priority"
                    ]
                  }
                }
              },
              "required": [
                "workDate",
                "status",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "workMinutes",
                "creditedMinutes",
                "targetMinutes",
                "balanceDeltaMinutes",
                "runningBalanceMinutes",
                "overtimeMinutes",
                "dayType",
                "sources",
                "deviations",
                "entries",
                "expectedSource",
                "workDayId"
              ]
            }
          }
        },
        "required": [
          "days"
        ]
      },
      "TeamBatchEntriesDto": {
        "type": "object",
        "properties": {
          "membershipIds": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "entries": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "entryTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2879
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "durationMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 1440
                },
                "note": {
                  "type": "string",
                  "maxLength": 200
                },
                "billable": {
                  "default": false,
                  "type": "boolean"
                },
                "billingBaseMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "allocations": {
                  "default": [],
                  "maxItems": 10,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "valueId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "weightBp": {
                        "default": 10000,
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 10000
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId"
                    ]
                  }
                },
                "taskId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                }
              },
              "required": [
                "entryTypeId"
              ]
            }
          },
          "breaks": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2880
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "breakTypeId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                }
              },
              "required": [
                "startMinutes",
                "endMinutes"
              ]
            }
          },
          "dayTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "membershipIds"
        ]
      },
      "TeamBatchEntriesResponseDto": {
        "type": "object",
        "properties": {
          "actedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skippedCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "code": {
                  "type": "string"
                }
              },
              "required": [
                "membershipId",
                "code"
              ]
            }
          }
        },
        "required": [
          "actedCount",
          "skippedCount",
          "skipped"
        ]
      },
      "WorkDayRegisterPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "membershipId": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "confirmed",
                    "approved",
                    "exported"
                  ]
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "workedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "creditedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "dayTypeId": {
                  "type": "string",
                  "nullable": true
                },
                "expectedTargetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "exportBatchId": {
                  "type": "string",
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                }
              },
              "required": [
                "id",
                "membershipId",
                "workDate",
                "status",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "workedMinutes",
                "creditedMinutes",
                "dayTypeId",
                "expectedTargetMinutes",
                "exportBatchId",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "ContactListResponseDto": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string"
                },
                "firstName": {
                  "type": "string",
                  "nullable": true
                },
                "lastName": {
                  "type": "string",
                  "nullable": true
                },
                "title": {
                  "type": "string",
                  "nullable": true
                },
                "email": {
                  "type": "string",
                  "nullable": true
                },
                "phone": {
                  "type": "string",
                  "nullable": true
                },
                "role": {
                  "type": "string",
                  "nullable": true
                },
                "isPrimary": {
                  "type": "boolean"
                },
                "notes": {
                  "type": "string",
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "anonymizedAt": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "firstName",
                "lastName",
                "title",
                "email",
                "phone",
                "role",
                "isPrimary",
                "notes",
                "active",
                "anonymizedAt",
                "createdAt",
                "updatedAt"
              ]
            }
          }
        },
        "required": [
          "contacts"
        ]
      },
      "CreateContactDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "lastName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "title": {
            "type": "string",
            "maxLength": 100
          },
          "email": {
            "type": "string",
            "maxLength": 200,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "phone": {
            "type": "string",
            "maxLength": 50
          },
          "role": {
            "type": "string",
            "maxLength": 100
          },
          "isPrimary": {
            "type": "boolean"
          },
          "notes": {
            "type": "string",
            "maxLength": 4000
          }
        },
        "required": [
          "firstName",
          "lastName"
        ]
      },
      "ContactViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "customerId": {
            "type": "string"
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "nullable": true
          },
          "isPrimary": {
            "type": "boolean"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "active": {
            "type": "boolean"
          },
          "anonymizedAt": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "customerId",
          "firstName",
          "lastName",
          "title",
          "email",
          "phone",
          "role",
          "isPrimary",
          "notes",
          "active",
          "anonymizedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "UpdateContactDto": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "lastName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "title": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "email": {
            "type": "string",
            "maxLength": 200,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "role": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "isPrimary": {
            "type": "boolean"
          },
          "notes": {
            "type": "string",
            "maxLength": 4000,
            "nullable": true
          },
          "active": {
            "type": "boolean"
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "Customer360ViewDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string"
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string"
                },
                "firstName": {
                  "type": "string",
                  "nullable": true
                },
                "lastName": {
                  "type": "string",
                  "nullable": true
                },
                "title": {
                  "type": "string",
                  "nullable": true
                },
                "email": {
                  "type": "string",
                  "nullable": true
                },
                "phone": {
                  "type": "string",
                  "nullable": true
                },
                "role": {
                  "type": "string",
                  "nullable": true
                },
                "isPrimary": {
                  "type": "boolean"
                },
                "notes": {
                  "type": "string",
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "anonymizedAt": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "firstName",
                "lastName",
                "title",
                "email",
                "phone",
                "role",
                "isPrimary",
                "notes",
                "active",
                "anonymizedAt",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "name",
                "color"
              ]
            }
          },
          "metrics": {
            "type": "object",
            "properties": {
              "openPipelineCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "wonCents12mo": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "lostCents12mo": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "invoicedLifetimeCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "marginLifetimeCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "lastActivityAt": {
                "type": "string",
                "nullable": true
              },
              "arOpenCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "arOverdueCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "lifetimeMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              }
            },
            "required": [
              "openPipelineCents",
              "wonCents12mo",
              "lostCents12mo",
              "invoicedLifetimeCents",
              "marginLifetimeCents",
              "lastActivityAt",
              "arOpenCents",
              "arOverdueCents",
              "lifetimeMinutes"
            ]
          },
          "openDeals": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string"
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "pipelineId": {
                  "type": "string"
                },
                "stageId": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "valueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "probabilityPercent": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "effectiveProbabilityPercent": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "expectedCloseDate": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "ownerName": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "open",
                    "won",
                    "lost"
                  ]
                },
                "lostReasonId": {
                  "type": "string",
                  "nullable": true
                },
                "lostComment": {
                  "type": "string",
                  "nullable": true
                },
                "wonAt": {
                  "type": "string",
                  "nullable": true
                },
                "lostAt": {
                  "type": "string",
                  "nullable": true
                },
                "sourceLeadId": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "nextActivityAt": {
                  "type": "string",
                  "nullable": true
                },
                "stageEnteredAt": {
                  "type": "string"
                },
                "stale": {
                  "type": "boolean"
                },
                "tagIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "contactId",
                "pipelineId",
                "stageId",
                "title",
                "valueCents",
                "probabilityPercent",
                "effectiveProbabilityPercent",
                "expectedCloseDate",
                "ownerMembershipId",
                "ownerName",
                "customerName",
                "status",
                "lostReasonId",
                "lostComment",
                "wonAt",
                "lostAt",
                "sourceLeadId",
                "projectId",
                "projectName",
                "nextActivityAt",
                "stageEnteredAt",
                "stale",
                "tagIds",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "recentActivities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "dealId": {
                  "type": "string",
                  "nullable": true
                },
                "leadId": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "call",
                    "meeting",
                    "email",
                    "note",
                    "task"
                  ]
                },
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string",
                  "nullable": true
                },
                "dueAt": {
                  "type": "string",
                  "nullable": true
                },
                "doneAt": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "createdByMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "customerName",
                "contactId",
                "dealId",
                "leadId",
                "projectId",
                "projectName",
                "type",
                "subject",
                "body",
                "dueAt",
                "doneAt",
                "ownerMembershipId",
                "createdByMembershipId",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "timelineItems": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "quote_sent",
                    "quote_accepted",
                    "quote_declined",
                    "deal_won",
                    "deal_lost",
                    "deal_reopened",
                    "project_status"
                  ]
                },
                "at": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                }
              },
              "required": [
                "id",
                "type",
                "at",
                "title",
                "amountCents"
              ]
            }
          }
        },
        "required": [
          "customerId",
          "contacts",
          "tags",
          "metrics",
          "openDeals",
          "recentActivities",
          "timelineItems"
        ]
      },
      "LeadPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "companyName": {
                  "type": "string",
                  "nullable": true
                },
                "businessId": {
                  "type": "string",
                  "nullable": true
                },
                "personName": {
                  "type": "string",
                  "nullable": true
                },
                "email": {
                  "type": "string",
                  "nullable": true
                },
                "phone": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "manual",
                    "intake",
                    "import",
                    "website",
                    "referral",
                    "other"
                  ]
                },
                "notes": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "new",
                    "working",
                    "converted",
                    "discarded"
                  ]
                },
                "discardReason": {
                  "type": "string",
                  "nullable": true
                },
                "convertedDealId": {
                  "type": "string",
                  "nullable": true
                },
                "convertedCustomerId": {
                  "type": "string",
                  "nullable": true
                },
                "anonymizedAt": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "title",
                "companyName",
                "businessId",
                "personName",
                "email",
                "phone",
                "source",
                "notes",
                "ownerMembershipId",
                "status",
                "discardReason",
                "convertedDealId",
                "convertedCustomerId",
                "anonymizedAt",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateLeadDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "companyName": {
            "type": "string",
            "maxLength": 200
          },
          "businessId": {
            "type": "string",
            "maxLength": 20
          },
          "personName": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": "string",
            "maxLength": 200,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "phone": {
            "type": "string",
            "maxLength": 50
          },
          "source": {
            "default": "manual",
            "type": "string",
            "enum": [
              "manual",
              "intake",
              "import",
              "website",
              "referral",
              "other"
            ]
          },
          "notes": {
            "type": "string",
            "maxLength": 4000
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "title"
        ]
      },
      "LeadViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "businessId": {
            "type": "string",
            "nullable": true
          },
          "personName": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "intake",
              "import",
              "website",
              "referral",
              "other"
            ]
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "working",
              "converted",
              "discarded"
            ]
          },
          "discardReason": {
            "type": "string",
            "nullable": true
          },
          "convertedDealId": {
            "type": "string",
            "nullable": true
          },
          "convertedCustomerId": {
            "type": "string",
            "nullable": true
          },
          "anonymizedAt": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "companyName",
          "businessId",
          "personName",
          "email",
          "phone",
          "source",
          "notes",
          "ownerMembershipId",
          "status",
          "discardReason",
          "convertedDealId",
          "convertedCustomerId",
          "anonymizedAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "UpdateLeadDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "companyName": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "businessId": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "personName": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "email": {
            "type": "string",
            "maxLength": 200,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "intake",
              "import",
              "website",
              "referral",
              "other"
            ]
          },
          "notes": {
            "type": "string",
            "maxLength": 4000,
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "ConvertLeadDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "newCustomerCode": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
          },
          "newCustomerName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "pipelineId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "dealTitle": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "valueCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2000000000
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "dealTitle"
        ]
      },
      "ConvertLeadResponseDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string"
          },
          "contactId": {
            "type": "string",
            "nullable": true
          },
          "dealId": {
            "type": "string"
          }
        },
        "required": [
          "customerId",
          "contactId",
          "dealId"
        ]
      },
      "PipelineListResponseDto": {
        "type": "object",
        "properties": {
          "pipelines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "active": {
                  "type": "boolean"
                },
                "isDefault": {
                  "type": "boolean"
                },
                "stages": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "pipelineId": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "sortOrder": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "probabilityPercent": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "staleAfterDays": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "pipelineId",
                      "name",
                      "sortOrder",
                      "probabilityPercent",
                      "staleAfterDays"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "name",
                "sortOrder",
                "active",
                "isDefault",
                "stages"
              ]
            }
          }
        },
        "required": [
          "pipelines"
        ]
      },
      "DealPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string"
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "pipelineId": {
                  "type": "string"
                },
                "stageId": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "valueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "probabilityPercent": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "effectiveProbabilityPercent": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "expectedCloseDate": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "ownerName": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "open",
                    "won",
                    "lost"
                  ]
                },
                "lostReasonId": {
                  "type": "string",
                  "nullable": true
                },
                "lostComment": {
                  "type": "string",
                  "nullable": true
                },
                "wonAt": {
                  "type": "string",
                  "nullable": true
                },
                "lostAt": {
                  "type": "string",
                  "nullable": true
                },
                "sourceLeadId": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "nextActivityAt": {
                  "type": "string",
                  "nullable": true
                },
                "stageEnteredAt": {
                  "type": "string"
                },
                "stale": {
                  "type": "boolean"
                },
                "tagIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "contactId",
                "pipelineId",
                "stageId",
                "title",
                "valueCents",
                "probabilityPercent",
                "effectiveProbabilityPercent",
                "expectedCloseDate",
                "ownerMembershipId",
                "ownerName",
                "customerName",
                "status",
                "lostReasonId",
                "lostComment",
                "wonAt",
                "lostAt",
                "sourceLeadId",
                "projectId",
                "projectName",
                "nextActivityAt",
                "stageEnteredAt",
                "stale",
                "tagIds",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateDealDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "pipelineId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "stageId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "valueCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2000000000
          },
          "probabilityPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "expectedCloseDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "tagIds": {
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        },
        "required": [
          "customerId",
          "title"
        ]
      },
      "DealViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "customerId": {
            "type": "string"
          },
          "contactId": {
            "type": "string",
            "nullable": true
          },
          "pipelineId": {
            "type": "string"
          },
          "stageId": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "valueCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "probabilityPercent": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "effectiveProbabilityPercent": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "expectedCloseDate": {
            "type": "string",
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string"
          },
          "ownerName": {
            "type": "string",
            "nullable": true
          },
          "customerName": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "won",
              "lost"
            ]
          },
          "lostReasonId": {
            "type": "string",
            "nullable": true
          },
          "lostComment": {
            "type": "string",
            "nullable": true
          },
          "wonAt": {
            "type": "string",
            "nullable": true
          },
          "lostAt": {
            "type": "string",
            "nullable": true
          },
          "sourceLeadId": {
            "type": "string",
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "nullable": true
          },
          "projectName": {
            "type": "string",
            "nullable": true
          },
          "nextActivityAt": {
            "type": "string",
            "nullable": true
          },
          "stageEnteredAt": {
            "type": "string"
          },
          "stale": {
            "type": "boolean"
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "customerId",
          "contactId",
          "pipelineId",
          "stageId",
          "title",
          "valueCents",
          "probabilityPercent",
          "effectiveProbabilityPercent",
          "expectedCloseDate",
          "ownerMembershipId",
          "ownerName",
          "customerName",
          "status",
          "lostReasonId",
          "lostComment",
          "wonAt",
          "lostAt",
          "sourceLeadId",
          "projectId",
          "projectName",
          "nextActivityAt",
          "stageEnteredAt",
          "stale",
          "tagIds",
          "createdAt",
          "updatedAt"
        ]
      },
      "UpdateDealDto": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "valueCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2000000000,
            "nullable": true
          },
          "probabilityPercent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "expectedCloseDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "MoveDealStageDto": {
        "type": "object",
        "properties": {
          "stageId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "beforeDealId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "stageId"
        ]
      },
      "WinDealDto": {
        "type": "object",
        "properties": {
          "comment": {
            "type": "string",
            "maxLength": 1000
          },
          "linkProjectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "LoseDealDto": {
        "type": "object",
        "properties": {
          "lostReasonId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "lostComment": {
            "type": "string",
            "maxLength": 1000
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "lostReasonId"
        ]
      },
      "BoardViewDto": {
        "type": "object",
        "properties": {
          "pipeline": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "sortOrder": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "active": {
                "type": "boolean"
              },
              "isDefault": {
                "type": "boolean"
              },
              "stages": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "pipelineId": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "sortOrder": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "probabilityPercent": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "staleAfterDays": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    }
                  },
                  "required": [
                    "id",
                    "pipelineId",
                    "name",
                    "sortOrder",
                    "probabilityPercent",
                    "staleAfterDays"
                  ]
                }
              }
            },
            "required": [
              "id",
              "name",
              "sortOrder",
              "active",
              "isDefault",
              "stages"
            ]
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "stage": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "pipelineId": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "sortOrder": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "probabilityPercent": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "staleAfterDays": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    }
                  },
                  "required": [
                    "id",
                    "pipelineId",
                    "name",
                    "sortOrder",
                    "probabilityPercent",
                    "staleAfterDays"
                  ]
                },
                "deals": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "customerId": {
                        "type": "string"
                      },
                      "contactId": {
                        "type": "string",
                        "nullable": true
                      },
                      "pipelineId": {
                        "type": "string"
                      },
                      "stageId": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      },
                      "valueCents": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "probabilityPercent": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "effectiveProbabilityPercent": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "expectedCloseDate": {
                        "type": "string",
                        "nullable": true
                      },
                      "ownerMembershipId": {
                        "type": "string"
                      },
                      "ownerName": {
                        "type": "string",
                        "nullable": true
                      },
                      "customerName": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "open",
                          "won",
                          "lost"
                        ]
                      },
                      "lostReasonId": {
                        "type": "string",
                        "nullable": true
                      },
                      "lostComment": {
                        "type": "string",
                        "nullable": true
                      },
                      "wonAt": {
                        "type": "string",
                        "nullable": true
                      },
                      "lostAt": {
                        "type": "string",
                        "nullable": true
                      },
                      "sourceLeadId": {
                        "type": "string",
                        "nullable": true
                      },
                      "projectId": {
                        "type": "string",
                        "nullable": true
                      },
                      "projectName": {
                        "type": "string",
                        "nullable": true
                      },
                      "nextActivityAt": {
                        "type": "string",
                        "nullable": true
                      },
                      "stageEnteredAt": {
                        "type": "string"
                      },
                      "stale": {
                        "type": "boolean"
                      },
                      "tagIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "createdAt": {
                        "type": "string"
                      },
                      "updatedAt": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "customerId",
                      "contactId",
                      "pipelineId",
                      "stageId",
                      "title",
                      "valueCents",
                      "probabilityPercent",
                      "effectiveProbabilityPercent",
                      "expectedCloseDate",
                      "ownerMembershipId",
                      "ownerName",
                      "customerName",
                      "status",
                      "lostReasonId",
                      "lostComment",
                      "wonAt",
                      "lostAt",
                      "sourceLeadId",
                      "projectId",
                      "projectName",
                      "nextActivityAt",
                      "stageEnteredAt",
                      "stale",
                      "tagIds",
                      "createdAt",
                      "updatedAt"
                    ]
                  }
                },
                "dealCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "valueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "weightedValueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "staleCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "stage",
                "deals",
                "dealCount",
                "valueCents",
                "weightedValueCents",
                "staleCount"
              ]
            }
          }
        },
        "required": [
          "pipeline",
          "columns"
        ]
      },
      "ActivityPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "dealId": {
                  "type": "string",
                  "nullable": true
                },
                "leadId": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "call",
                    "meeting",
                    "email",
                    "note",
                    "task"
                  ]
                },
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string",
                  "nullable": true
                },
                "dueAt": {
                  "type": "string",
                  "nullable": true
                },
                "doneAt": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "createdByMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "customerName",
                "contactId",
                "dealId",
                "leadId",
                "projectId",
                "projectName",
                "type",
                "subject",
                "body",
                "dueAt",
                "doneAt",
                "ownerMembershipId",
                "createdByMembershipId",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "ActivityAgendaResponseDto": {
        "type": "object",
        "properties": {
          "overdue": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "dealId": {
                  "type": "string",
                  "nullable": true
                },
                "leadId": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "call",
                    "meeting",
                    "email",
                    "note",
                    "task"
                  ]
                },
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string",
                  "nullable": true
                },
                "dueAt": {
                  "type": "string",
                  "nullable": true
                },
                "doneAt": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "createdByMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "customerName",
                "contactId",
                "dealId",
                "leadId",
                "projectId",
                "projectName",
                "type",
                "subject",
                "body",
                "dueAt",
                "doneAt",
                "ownerMembershipId",
                "createdByMembershipId",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "today": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "dealId": {
                  "type": "string",
                  "nullable": true
                },
                "leadId": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "call",
                    "meeting",
                    "email",
                    "note",
                    "task"
                  ]
                },
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string",
                  "nullable": true
                },
                "dueAt": {
                  "type": "string",
                  "nullable": true
                },
                "doneAt": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "createdByMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "customerName",
                "contactId",
                "dealId",
                "leadId",
                "projectId",
                "projectName",
                "type",
                "subject",
                "body",
                "dueAt",
                "doneAt",
                "ownerMembershipId",
                "createdByMembershipId",
                "createdAt",
                "updatedAt"
              ]
            }
          }
        },
        "required": [
          "overdue",
          "today"
        ]
      },
      "CreateActivityDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "dealId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "leadId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "type": {
            "type": "string",
            "enum": [
              "call",
              "meeting",
              "email",
              "note",
              "task"
            ]
          },
          "subject": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "body": {
            "type": "string",
            "maxLength": 8000
          },
          "dueAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "type",
          "subject"
        ]
      },
      "ActivityViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "customerId": {
            "type": "string",
            "nullable": true
          },
          "customerName": {
            "type": "string",
            "nullable": true
          },
          "contactId": {
            "type": "string",
            "nullable": true
          },
          "dealId": {
            "type": "string",
            "nullable": true
          },
          "leadId": {
            "type": "string",
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "nullable": true
          },
          "projectName": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "enum": [
              "call",
              "meeting",
              "email",
              "note",
              "task"
            ]
          },
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "dueAt": {
            "type": "string",
            "nullable": true
          },
          "doneAt": {
            "type": "string",
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string"
          },
          "createdByMembershipId": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "customerId",
          "customerName",
          "contactId",
          "dealId",
          "leadId",
          "projectId",
          "projectName",
          "type",
          "subject",
          "body",
          "dueAt",
          "doneAt",
          "ownerMembershipId",
          "createdByMembershipId",
          "createdAt",
          "updatedAt"
        ]
      },
      "ToggleActivityDoneDto": {
        "type": "object",
        "properties": {
          "done": {
            "type": "boolean"
          }
        },
        "required": [
          "done"
        ]
      },
      "ApiKeyListResponseDto": {
        "type": "object",
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "personal",
                    "service"
                  ]
                },
                "ownerMembershipId": {
                  "type": "string"
                },
                "ownerName": {
                  "type": "string",
                  "nullable": true
                },
                "ownerActive": {
                  "type": "boolean",
                  "nullable": true
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "tokenPrefix": {
                  "type": "string"
                },
                "capabilities": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "worktime.supervise",
                      "scheduling.plan",
                      "scheduling.admin",
                      "projects.manage",
                      "projects.read",
                      "crm.use",
                      "crm.admin",
                      "hr.manage",
                      "hr.record",
                      "payroll.run",
                      "reports.team",
                      "members.manage",
                      "comms.announce",
                      "integrations.manage",
                      "org.admin"
                    ]
                  }
                },
                "readOnly": {
                  "type": "boolean"
                },
                "expiresAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "requests7d": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "errors7d": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "lastUsedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "revokedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "name",
                "kind",
                "ownerMembershipId",
                "ownerName",
                "ownerActive",
                "description",
                "tokenPrefix",
                "capabilities",
                "readOnly",
                "expiresAt",
                "requests7d",
                "errors7d",
                "createdAt",
                "lastUsedAt",
                "revokedAt"
              ]
            }
          }
        },
        "required": [
          "keys"
        ]
      },
      "CreateServiceApiKeyDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 300
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "capabilities": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "worktime.supervise",
                "scheduling.plan",
                "scheduling.admin",
                "projects.manage",
                "projects.read",
                "crm.use",
                "crm.admin",
                "hr.manage",
                "hr.record",
                "payroll.run",
                "reports.team",
                "members.manage",
                "comms.announce",
                "integrations.manage",
                "org.admin"
              ]
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "readOnly": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "ownerMembershipId",
          "capabilities"
        ]
      },
      "CreateApiKeyResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "token": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "token"
        ]
      },
      "ReassignApiKeyDto": {
        "type": "object",
        "properties": {
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "ownerMembershipId"
        ]
      },
      "ApiKeyOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "CreateApiKeyDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 300
          },
          "capabilities": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "worktime.supervise",
                "scheduling.plan",
                "scheduling.admin",
                "projects.manage",
                "projects.read",
                "crm.use",
                "crm.admin",
                "hr.manage",
                "hr.record",
                "payroll.run",
                "reports.team",
                "members.manage",
                "comms.announce",
                "integrations.manage",
                "org.admin"
              ]
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "readOnly": {
            "type": "boolean"
          }
        },
        "required": [
          "name"
        ]
      },
      "RotateApiKeyResponseDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          }
        },
        "required": [
          "token"
        ]
      },
      "AccessContextDto": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string"
          },
          "membershipId": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "worktime.supervise",
                "scheduling.plan",
                "scheduling.admin",
                "projects.manage",
                "projects.read",
                "crm.use",
                "crm.admin",
                "hr.manage",
                "hr.record",
                "payroll.run",
                "reports.team",
                "members.manage",
                "comms.announce",
                "integrations.manage",
                "org.admin"
              ]
            }
          },
          "apiKey": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "personal",
                  "service"
                ]
              },
              "scope": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "worktime.supervise",
                    "scheduling.plan",
                    "scheduling.admin",
                    "projects.manage",
                    "projects.read",
                    "crm.use",
                    "crm.admin",
                    "hr.manage",
                    "hr.record",
                    "payroll.run",
                    "reports.team",
                    "members.manage",
                    "comms.announce",
                    "integrations.manage",
                    "org.admin"
                  ]
                }
              },
              "readOnly": {
                "type": "boolean"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                "nullable": true
              }
            },
            "required": [
              "id",
              "kind",
              "scope",
              "readOnly",
              "expiresAt"
            ],
            "nullable": true
          },
          "oauth": {
            "type": "object",
            "properties": {
              "grantId": {
                "type": "string"
              },
              "clientName": {
                "type": "string"
              },
              "scope": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "worktime.supervise",
                    "scheduling.plan",
                    "scheduling.admin",
                    "projects.manage",
                    "projects.read",
                    "crm.use",
                    "crm.admin",
                    "hr.manage",
                    "hr.record",
                    "payroll.run",
                    "reports.team",
                    "members.manage",
                    "comms.announce",
                    "integrations.manage",
                    "org.admin"
                  ]
                }
              },
              "resource": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "grantId",
              "clientName",
              "scope",
              "resource"
            ],
            "nullable": true
          },
          "rateLimits": {
            "type": "object",
            "properties": {
              "perKeyPerMinute": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "perTenantPerMinute": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "perKeyPerMinute",
              "perTenantPerMinute"
            ]
          }
        },
        "required": [
          "tenantId",
          "membershipId",
          "role",
          "capabilities",
          "apiKey",
          "oauth",
          "rateLimits"
        ]
      },
      "OAuthGrantListResponseDto": {
        "type": "object",
        "properties": {
          "grants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "clientName": {
                  "type": "string"
                },
                "clientUri": {
                  "type": "string",
                  "nullable": true
                },
                "scopes": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "worktime.supervise",
                      "scheduling.plan",
                      "scheduling.admin",
                      "projects.manage",
                      "projects.read",
                      "crm.use",
                      "crm.admin",
                      "hr.manage",
                      "hr.record",
                      "payroll.run",
                      "reports.team",
                      "members.manage",
                      "comms.announce",
                      "integrations.manage",
                      "org.admin"
                    ]
                  }
                },
                "resource": {
                  "type": "string",
                  "nullable": true
                },
                "memberName": {
                  "type": "string",
                  "nullable": true
                },
                "membershipId": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "lastUsedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "clientName",
                "clientUri",
                "scopes",
                "resource",
                "memberName",
                "membershipId",
                "createdAt",
                "lastUsedAt"
              ]
            }
          }
        },
        "required": [
          "grants"
        ]
      },
      "OAuthGrantOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "ShiftPlanResponseDto": {
        "type": "object",
        "properties": {
          "planningUnitId": {
            "type": "string"
          },
          "groupShifts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "membershipId": {
                  "type": "string",
                  "nullable": true
                },
                "planningUnitId": {
                  "type": "string",
                  "nullable": true
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "shift",
                    "off"
                  ]
                },
                "shiftTypeId": {
                  "type": "string",
                  "nullable": true
                },
                "positionId": {
                  "type": "string",
                  "nullable": true
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "drivingMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "publishedAt": {
                  "type": "string",
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                },
                "segments": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "breakMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "breakMinutes",
                      "targetMinutes"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "workDate",
                "membershipId",
                "planningUnitId",
                "kind",
                "shiftTypeId",
                "positionId",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "targetMinutes",
                "note",
                "publishedAt",
                "updatedAt",
                "segments"
              ]
            }
          },
          "members": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "employmentStartDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "employmentEndDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "shifts": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "workDate": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "membershipId": {
                        "type": "string",
                        "nullable": true
                      },
                      "planningUnitId": {
                        "type": "string",
                        "nullable": true
                      },
                      "kind": {
                        "type": "string",
                        "enum": [
                          "shift",
                          "off"
                        ]
                      },
                      "shiftTypeId": {
                        "type": "string",
                        "nullable": true
                      },
                      "positionId": {
                        "type": "string",
                        "nullable": true
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440,
                        "nullable": true
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880,
                        "nullable": true
                      },
                      "breakMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "note": {
                        "type": "string",
                        "nullable": true
                      },
                      "publishedAt": {
                        "type": "string",
                        "nullable": true
                      },
                      "updatedAt": {
                        "type": "string"
                      },
                      "segments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "startMinutes": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 1440
                            },
                            "endMinutes": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 2880
                            },
                            "breakMinutes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "targetMinutes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "drivingMinutes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "nullable": true
                            }
                          },
                          "required": [
                            "startMinutes",
                            "endMinutes",
                            "breakMinutes",
                            "targetMinutes"
                          ]
                        }
                      }
                    },
                    "required": [
                      "id",
                      "workDate",
                      "membershipId",
                      "planningUnitId",
                      "kind",
                      "shiftTypeId",
                      "positionId",
                      "startMinutes",
                      "endMinutes",
                      "breakMinutes",
                      "targetMinutes",
                      "note",
                      "publishedAt",
                      "updatedAt",
                      "segments"
                    ]
                  }
                },
                "contextShifts": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "workDate": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "planningUnitId": {
                        "type": "string"
                      },
                      "unitName": {
                        "type": "string"
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      }
                    },
                    "required": [
                      "workDate",
                      "planningUnitId",
                      "unitName",
                      "startMinutes",
                      "endMinutes"
                    ]
                  }
                },
                "contractTargetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "flexBalanceMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "managerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "staffGroupIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "employmentStartDate",
                "employmentEndDate",
                "shifts",
                "contextShifts",
                "contractTargetMinutes",
                "flexBalanceMinutes",
                "managerMembershipId",
                "staffGroupIds"
              ]
            }
          },
          "coverage": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "requirementId": {
                  "type": "string"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "requiredCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "positionId": {
                  "type": "string",
                  "nullable": true
                },
                "plannedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "shortfall": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "uncoveredPersonMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "surplusPersonMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "skillGaps": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "skillIds": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "requiredCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "plannedCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "shortfall": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "skillIds",
                      "requiredCount",
                      "plannedCount",
                      "shortfall"
                    ]
                  }
                },
                "skillExpiry": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "skillId": {
                        "type": "string"
                      },
                      "expiredCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "expiringCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "skillId",
                      "expiredCount",
                      "expiringCount"
                    ]
                  }
                },
                "understaffed": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "from": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "to": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "plannedCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "from",
                      "to",
                      "plannedCount"
                    ]
                  }
                }
              },
              "required": [
                "workDate",
                "requirementId",
                "startMinutes",
                "endMinutes",
                "requiredCount",
                "positionId",
                "plannedCount",
                "shortfall",
                "uncoveredPersonMinutes",
                "surplusPersonMinutes",
                "skillGaps",
                "skillExpiry",
                "understaffed"
              ]
            }
          },
          "conflicts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "shift-on-absence",
                    "shift-outside-employment"
                  ]
                }
              },
              "required": [
                "membershipId",
                "workDate",
                "type"
              ]
            }
          },
          "avoidPairConflicts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "aMembershipId": {
                  "type": "string"
                },
                "bMembershipId": {
                  "type": "string"
                },
                "aDisplayName": {
                  "type": "string"
                },
                "bDisplayName": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                }
              },
              "required": [
                "aMembershipId",
                "bMembershipId",
                "aDisplayName",
                "bDisplayName",
                "workDate"
              ]
            }
          },
          "complianceViolations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "daily_rest",
                    "weekly_rest",
                    "period_cap",
                    "consecutive_days",
                    "consecutive_nights",
                    "min_shift",
                    "max_shift",
                    "long_shift_count",
                    "forbidden_start",
                    "forbidden_end",
                    "split_gap",
                    "split_span",
                    "split_count",
                    "night_recovery",
                    "weekly_days_off",
                    "weekend_rest",
                    "free_sunday",
                    "consecutive_free_days",
                    "break_required",
                    "rest_debt",
                    "multi_period_cap",
                    "sub_period_cap",
                    "long_window_avg",
                    "v_free_count",
                    "break_placement",
                    "competence_missing",
                    "competence_below_level",
                    "competence_expired",
                    "competence_expiring"
                  ]
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "hard",
                    "soft"
                  ]
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "law",
                    "tes",
                    "unit"
                  ]
                },
                "dates": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  }
                },
                "actual": {
                  "type": "number"
                },
                "limit": {
                  "type": "number"
                }
              },
              "required": [
                "membershipId",
                "type",
                "severity",
                "source",
                "dates",
                "actual",
                "limit"
              ]
            }
          },
          "workdayLengthMinutes": {
            "type": "integer",
            "exclusiveMinimum": true,
            "maximum": 9007199254740991,
            "minimum": 0
          },
          "cancelDeadlineDaysBefore": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "cancelDeadlineTimeMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1439,
            "nullable": true
          },
          "rotationDeviations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "type_changed",
                    "times_changed",
                    "expected_work_missing",
                    "expected_off_working"
                  ]
                },
                "expectedKind": {
                  "type": "string",
                  "enum": [
                    "shift",
                    "off"
                  ]
                },
                "expectedShiftTypeNameFi": {
                  "type": "string",
                  "nullable": true
                },
                "expectedShiftTypeNameSv": {
                  "type": "string",
                  "nullable": true
                },
                "expectedShiftTypeNameEn": {
                  "type": "string",
                  "nullable": true
                },
                "expectedStartMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "expectedEndMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                }
              },
              "required": [
                "membershipId",
                "workDate",
                "kind",
                "expectedKind",
                "expectedShiftTypeNameFi",
                "expectedShiftTypeNameSv",
                "expectedShiftTypeNameEn",
                "expectedStartMinutes",
                "expectedEndMinutes"
              ]
            }
          },
          "holidayDates": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "planningUnitId",
          "groupShifts",
          "members",
          "coverage",
          "conflicts",
          "avoidPairConflicts",
          "complianceViolations",
          "workdayLengthMinutes",
          "cancelDeadlineDaysBefore",
          "cancelDeadlineTimeMinutes",
          "rotationDeviations",
          "holidayDates"
        ]
      },
      "UncoveredShiftListResponseDto": {
        "type": "object",
        "properties": {
          "shifts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "shiftId": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "membershipId": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string",
                  "nullable": true
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "positionId": {
                  "type": "string",
                  "nullable": true
                },
                "shiftTypeId": {
                  "type": "string",
                  "nullable": true
                },
                "segments": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "breakMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "breakMinutes",
                      "targetMinutes"
                    ]
                  }
                },
                "absenceName": {
                  "type": "object",
                  "properties": {
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "nameFi",
                    "nameSv",
                    "nameEn"
                  ],
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "needs_cover",
                    "released",
                    "filled",
                    "cover_no_longer_needed"
                  ]
                },
                "openShiftId": {
                  "type": "string",
                  "nullable": true
                },
                "requiredSkillIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "requiredSkills": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "skillId": {
                        "type": "string"
                      },
                      "nameFi": {
                        "type": "string"
                      },
                      "nameSv": {
                        "type": "string"
                      },
                      "nameEn": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "skillId",
                      "nameFi",
                      "nameSv",
                      "nameEn"
                    ]
                  }
                }
              },
              "required": [
                "shiftId",
                "workDate",
                "membershipId",
                "memberName",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "targetMinutes",
                "positionId",
                "shiftTypeId",
                "segments",
                "absenceName",
                "status",
                "openShiftId",
                "requiredSkillIds",
                "requiredSkills"
              ]
            }
          }
        },
        "required": [
          "shifts"
        ]
      },
      "SchedulingOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "PublishEventPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "planningUnitId": {
                  "type": "string"
                },
                "periodFrom": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "periodTo": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "publishedAt": {
                  "type": "string"
                },
                "publishedBy": {
                  "type": "string",
                  "nullable": true
                },
                "publishedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "recipientCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "delivery": {
                  "type": "object",
                  "properties": {
                    "sent": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "pending": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "failed": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "skipped": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "sent",
                    "pending",
                    "failed",
                    "skipped"
                  ]
                }
              },
              "required": [
                "id",
                "planningUnitId",
                "periodFrom",
                "periodTo",
                "publishedAt",
                "publishedBy",
                "publishedCount",
                "recipientCount",
                "delivery"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "PlanningUnitListResponseDto": {
        "type": "object",
        "properties": {
          "units": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "parentId": {
                  "type": "string",
                  "nullable": true
                },
                "costCenterValueId": {
                  "type": "string",
                  "nullable": true
                },
                "periodWorkWeeks": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "periodWorkAnchor": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "crossUnitOptOut": {
                  "type": "boolean"
                },
                "active": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "name",
                "parentId",
                "costCenterValueId",
                "periodWorkWeeks",
                "periodWorkAnchor",
                "crossUnitOptOut",
                "active",
                "sortOrder"
              ]
            }
          }
        },
        "required": [
          "units"
        ]
      },
      "MyShiftsResponseDto": {
        "type": "object",
        "properties": {
          "shifts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "shift",
                    "off"
                  ]
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "segments": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "breakMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "breakMinutes",
                      "targetMinutes"
                    ]
                  }
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "person-shift",
                    "group-shift"
                  ]
                },
                "shiftTypeNameFi": {
                  "type": "string",
                  "nullable": true
                },
                "shiftTypeNameSv": {
                  "type": "string",
                  "nullable": true
                },
                "shiftTypeNameEn": {
                  "type": "string",
                  "nullable": true
                },
                "shortCode": {
                  "type": "string",
                  "nullable": true
                },
                "color": {
                  "type": "string",
                  "nullable": true
                },
                "unitName": {
                  "type": "string",
                  "nullable": true
                },
                "publishedAt": {
                  "type": "string",
                  "nullable": true
                },
                "ackRequired": {
                  "type": "boolean"
                },
                "acknowledgedAt": {
                  "type": "string",
                  "nullable": true
                },
                "onApprovedAbsence": {
                  "type": "boolean"
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "deviatesFromRotation": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "workDate",
                "kind",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "targetMinutes",
                "segments",
                "source",
                "shiftTypeNameFi",
                "shiftTypeNameSv",
                "shiftTypeNameEn",
                "shortCode",
                "color",
                "unitName",
                "publishedAt",
                "ackRequired",
                "acknowledgedAt",
                "onApprovedAbsence",
                "note",
                "deviatesFromRotation"
              ]
            }
          },
          "dayNotes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "title": {
                  "type": "string"
                },
                "body": {
                  "type": "string"
                },
                "unitName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "date",
                "title",
                "body",
                "unitName"
              ]
            }
          },
          "ackRequired": {
            "type": "boolean"
          },
          "autonomousSchedulingEnabled": {
            "type": "boolean"
          },
          "employmentStartDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "employmentEndDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          }
        },
        "required": [
          "shifts",
          "dayNotes",
          "ackRequired",
          "autonomousSchedulingEnabled",
          "employmentStartDate",
          "employmentEndDate"
        ]
      },
      "OpenShiftPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "planningUnitId": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "shiftTypeId": {
                  "type": "string",
                  "nullable": true
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "segments": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "breakMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "breakMinutes",
                      "targetMinutes"
                    ]
                  }
                },
                "requiredSkillIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "requiredSkills": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "skillId": {
                        "type": "string"
                      },
                      "nameFi": {
                        "type": "string"
                      },
                      "nameSv": {
                        "type": "string"
                      },
                      "nameEn": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "skillId",
                      "nameFi",
                      "nameSv",
                      "nameEn"
                    ]
                  }
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "open",
                    "claimed",
                    "filled",
                    "cancelled"
                  ]
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "expiresAt": {
                  "type": "string",
                  "nullable": true
                },
                "cancelDeadline": {
                  "type": "string",
                  "nullable": true
                },
                "offerStage": {
                  "type": "string",
                  "enum": [
                    "unit",
                    "cross_unit",
                    "all"
                  ]
                },
                "escalateAfterMinutes": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "claims": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "membershipId": {
                        "type": "string"
                      },
                      "displayName": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "pending",
                          "approved",
                          "rejected",
                          "withdrawn"
                        ]
                      },
                      "createdAt": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "membershipId",
                      "displayName",
                      "status",
                      "createdAt"
                    ]
                  }
                },
                "myClaimStatus": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "approved",
                    "rejected",
                    "withdrawn",
                    null
                  ],
                  "nullable": true
                },
                "myClaimReason": {
                  "type": "string",
                  "nullable": true
                },
                "eligible": {
                  "type": "boolean"
                },
                "ineligibleReason": {
                  "type": "string",
                  "enum": [
                    "missing_skill",
                    "not_employed",
                    "already_scheduled",
                    null
                  ],
                  "nullable": true
                },
                "isCrossUnit": {
                  "type": "boolean"
                },
                "unitName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "planningUnitId",
                "date",
                "shiftTypeId",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "targetMinutes",
                "segments",
                "requiredSkillIds",
                "requiredSkills",
                "status",
                "reason",
                "createdAt",
                "expiresAt",
                "cancelDeadline",
                "offerStage",
                "escalateAfterMinutes"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "ClaimOpenShiftDto": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "maxLength": 100000
          }
        }
      },
      "ShiftSwapPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "requesterMembershipId": {
                  "type": "string"
                },
                "requesterDisplayName": {
                  "type": "string"
                },
                "requesterDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "counterpartyMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "counterpartyDisplayName": {
                  "type": "string",
                  "nullable": true
                },
                "counterpartyDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "isGiveAway": {
                  "type": "boolean"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "proposed",
                    "accepted",
                    "approved",
                    "rejected",
                    "withdrawn",
                    "cancelled"
                  ]
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "requesterMembershipId",
                "requesterDisplayName",
                "requesterDate",
                "counterpartyMembershipId",
                "counterpartyDisplayName",
                "counterpartyDate",
                "isGiveAway",
                "status",
                "reason",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "UnitRosterResponseDto": {
        "type": "object",
        "properties": {
          "shifts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "planningUnitId": {
                  "type": "string"
                },
                "planningUnitName": {
                  "type": "string"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440,
                  "nullable": true
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880,
                  "nullable": true
                },
                "breakMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "targetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "segments": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "breakMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      }
                    },
                    "required": [
                      "startMinutes",
                      "endMinutes",
                      "breakMinutes",
                      "targetMinutes"
                    ]
                  }
                },
                "shiftTypeNameFi": {
                  "type": "string",
                  "nullable": true
                },
                "shiftTypeNameSv": {
                  "type": "string",
                  "nullable": true
                },
                "shiftTypeNameEn": {
                  "type": "string",
                  "nullable": true
                },
                "shortCode": {
                  "type": "string",
                  "nullable": true
                },
                "color": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "planningUnitId",
                "planningUnitName",
                "workDate",
                "startMinutes",
                "endMinutes",
                "breakMinutes",
                "targetMinutes",
                "segments",
                "shiftTypeNameFi",
                "shiftTypeNameSv",
                "shiftTypeNameEn",
                "shortCode",
                "color"
              ]
            }
          },
          "units": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name"
              ]
            }
          }
        },
        "required": [
          "shifts",
          "units"
        ]
      },
      "ResolveClaimDto": {
        "type": "object",
        "properties": {
          "membershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500,
            "nullable": true
          }
        },
        "required": [
          "membershipId"
        ]
      },
      "RejectSwapDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500,
            "nullable": true
          }
        }
      },
      "DayTypeListResponseDto": {
        "type": "object",
        "properties": {
          "dayTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,49}$"
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "active": {
                  "type": "boolean"
                },
                "isSystem": {
                  "type": "boolean"
                },
                "locked": {
                  "type": "boolean"
                },
                "governedByPolicy": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "versions": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "validFrom": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "validTo": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "nullable": true
                      },
                      "creditsTarget": {
                        "type": "boolean"
                      },
                      "consumesFlex": {
                        "type": "boolean"
                      },
                      "consumesAccountTypeId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                        "nullable": true
                      },
                      "countsAsWorkTime": {
                        "type": "boolean"
                      },
                      "countsTowardMaxWorkTime": {
                        "type": "boolean"
                      },
                      "exportAsCount": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "id",
                      "validFrom",
                      "validTo",
                      "creditsTarget",
                      "consumesFlex",
                      "countsAsWorkTime",
                      "countsTowardMaxWorkTime",
                      "exportAsCount"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "active",
                "isSystem",
                "locked",
                "governedByPolicy",
                "sortOrder",
                "versions"
              ]
            }
          }
        },
        "required": [
          "dayTypes"
        ]
      },
      "EntryTypeListResponseDto": {
        "type": "object",
        "properties": {
          "entryTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,49}$"
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "active": {
                  "type": "boolean"
                },
                "isSystem": {
                  "type": "boolean"
                },
                "locked": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "versions": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "validFrom": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "validTo": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "nullable": true
                      },
                      "countsAsWorkTime": {
                        "type": "boolean"
                      },
                      "accruesFlex": {
                        "type": "boolean"
                      },
                      "creditsTarget": {
                        "default": false,
                        "type": "boolean"
                      },
                      "countsTowardMaxWorkTime": {
                        "type": "boolean"
                      },
                      "emergencyWork": {
                        "default": false,
                        "type": "boolean"
                      },
                      "requiresComment": {
                        "default": false,
                        "type": "boolean"
                      },
                      "paid": {
                        "type": "boolean"
                      },
                      "maxDurationMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "perEntryCreditCapMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "dailyCreditCapMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "creditBeyondTargetCapMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "unpaidFirstMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "worktimeFractionBp": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 10000,
                        "default": null,
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "validFrom",
                      "validTo",
                      "countsAsWorkTime",
                      "accruesFlex",
                      "countsTowardMaxWorkTime",
                      "paid",
                      "maxDurationMinutes"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "active",
                "isSystem",
                "locked",
                "sortOrder",
                "versions"
              ]
            }
          }
        },
        "required": [
          "entryTypes"
        ]
      },
      "BreakTypeListResponseDto": {
        "type": "object",
        "properties": {
          "breakTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "code": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 40
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                },
                "active": {
                  "type": "boolean"
                },
                "isSystem": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "versions": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "defaultMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "paidMode": {
                        "type": "string",
                        "enum": [
                          "unpaid",
                          "paid",
                          "paid_up_to"
                        ]
                      },
                      "paidCapMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "overflowTreatment": {
                        "type": "string",
                        "enum": [
                          "unpaid",
                          "paid",
                          "flag"
                        ]
                      },
                      "maxPerDay": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "maxPaidMinutesPerDay": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "satisfiesDailyBreakDuty": {
                        "type": "boolean"
                      },
                      "mustBeContinuous": {
                        "type": "boolean"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "validFrom": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "validTo": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "nullable": true
                      }
                    },
                    "required": [
                      "defaultMinutes",
                      "paidMode",
                      "paidCapMinutes",
                      "overflowTreatment",
                      "maxPerDay",
                      "maxPaidMinutesPerDay",
                      "satisfiesDailyBreakDuty",
                      "mustBeContinuous",
                      "id",
                      "validFrom",
                      "validTo"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "active",
                "isSystem",
                "sortOrder",
                "versions"
              ]
            }
          }
        },
        "required": [
          "breakTypes"
        ]
      },
      "ShiftTypeListResponseDto": {
        "type": "object",
        "properties": {
          "shiftTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "shortCode": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                },
                "active": {
                  "type": "boolean"
                },
                "isSystem": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "versions": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "validFrom": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "validTo": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "nullable": true
                      },
                      "startMinutes": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 1440
                      },
                      "endMinutes": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 2880
                      },
                      "targetMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "drivingMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "policy": {
                        "type": "object",
                        "properties": {
                          "breakDeductionMode": {
                            "type": "string",
                            "enum": [
                              "none",
                              "minimum",
                              "fixed"
                            ]
                          },
                          "breakThresholdMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "breakThresholdBasis": {
                            "type": "string",
                            "enum": [
                              "work",
                              "span"
                            ]
                          },
                          "minBreakMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "breakAnchorMinutes": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 1440,
                            "nullable": true
                          },
                          "paidCoffeeTotalMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "paidCoffeeMaxCount": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 9007199254740991
                          },
                          "flexWindowStartMinutes": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 1440
                          },
                          "flexWindowEndMinutes": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 1440
                          },
                          "dayFlexCapMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "dayFlexFloorMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "dailyRegularBasis": {
                            "type": "string",
                            "enum": [
                              "target",
                              "fixed"
                            ]
                          },
                          "dailyRegularFixedMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "dailyOt50Minutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "nullable": true
                          },
                          "flexRoundingMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "openPunchAutoClose": {
                            "type": "string",
                            "enum": [
                              "off",
                              "boundary",
                              "planned_end"
                            ]
                          },
                          "punchRoundingMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "punchGraceStartMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "punchGraceEndMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "prepMinMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "prepMaxCreditMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "wrapMinMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "wrapMaxCreditMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "prepWrapFixedCreditMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "prepWrapCountsTowardWeeklyOt": {
                            "type": "boolean"
                          },
                          "prepWrapDisposition": {
                            "type": "string",
                            "enum": [
                              "flex",
                              "payout",
                              "ignore",
                              "bank"
                            ]
                          },
                          "extendShortBreakToMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "shortenLongBreakToMinutes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "zeroBreakSuppressesAutoDeduct": {
                            "type": "boolean"
                          },
                          "defaultEntryTypeId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "nullable": true
                          },
                          "deductedBreakTypeId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "nullable": true
                          }
                        }
                      },
                      "segments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "startMinutes": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 1440
                            },
                            "endMinutes": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 2880
                            },
                            "breakMinutes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "targetMinutes": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            }
                          },
                          "required": [
                            "startMinutes",
                            "endMinutes",
                            "breakMinutes",
                            "targetMinutes"
                          ]
                        }
                      },
                      "clockWindows": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "weekday": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 7
                            },
                            "startMinutes": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 1440
                            },
                            "endMinutes": {
                              "type": "integer",
                              "minimum": 1,
                              "maximum": 2880
                            },
                            "kind": {
                              "type": "string",
                              "enum": [
                                "allowed",
                                "expected",
                                "ot_upgrade"
                              ]
                            }
                          },
                          "required": [
                            "weekday",
                            "startMinutes",
                            "endMinutes",
                            "kind"
                          ]
                        }
                      }
                    },
                    "required": [
                      "id",
                      "validFrom",
                      "validTo",
                      "startMinutes",
                      "endMinutes",
                      "targetMinutes",
                      "policy",
                      "segments",
                      "clockWindows"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "shortCode",
                "color",
                "active",
                "isSystem",
                "sortOrder",
                "versions"
              ]
            }
          }
        },
        "required": [
          "shiftTypes"
        ]
      },
      "BalanceTransactionListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "membershipId": {
                  "type": "string"
                },
                "accountTypeId": {
                  "type": "string"
                },
                "occurredOn": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "amountMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "initial",
                    "adjustment",
                    "transfer",
                    "usage",
                    "expiry",
                    "cut"
                  ]
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                },
                "sourceWorkDayId": {
                  "type": "string",
                  "nullable": true
                },
                "createdByMembershipId": {
                  "type": "string"
                },
                "createdByName": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "membershipId",
                "accountTypeId",
                "occurredOn",
                "amountMinutes",
                "kind",
                "reason",
                "sourceWorkDayId",
                "createdByMembershipId",
                "createdByName",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "BalanceAccountTypeListResponseDto": {
        "type": "object",
        "properties": {
          "accountTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "flex",
                    "overtime_bank",
                    "worktime_bank",
                    "shorter_worktime"
                  ]
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "accrualSource": {
                  "type": "string",
                  "enum": [
                    "projection",
                    "ledger"
                  ]
                },
                "capMaxMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "capMinMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "yearlyAccrualCapMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "isSystem": {
                  "type": "boolean"
                },
                "locked": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "overflowTargetAccountId": {
                  "type": "string",
                  "nullable": true
                },
                "overflowToPay": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "kind",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "accrualSource",
                "capMaxMinutes",
                "capMinMinutes",
                "yearlyAccrualCapMinutes",
                "active",
                "isSystem",
                "locked",
                "sortOrder",
                "overflowTargetAccountId",
                "overflowToPay"
              ]
            }
          }
        },
        "required": [
          "accountTypes"
        ]
      },
      "DimensionListResponseDto": {
        "type": "object",
        "properties": {
          "dimensions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "required": {
                  "type": "boolean"
                },
                "active": {
                  "type": "boolean"
                },
                "locked": {
                  "type": "boolean"
                },
                "allowsSplit": {
                  "default": false,
                  "type": "boolean"
                },
                "askInEntry": {
                  "default": true,
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "values": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "parentId": {
                        "type": "string",
                        "nullable": true
                      },
                      "code": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "active": {
                        "type": "boolean"
                      },
                      "sortOrder": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "path": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "defaultBillable": {
                        "type": "boolean",
                        "default": null,
                        "nullable": true
                      },
                      "customerName": {
                        "type": "string",
                        "default": null,
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "parentId",
                      "code",
                      "name",
                      "active",
                      "sortOrder"
                    ]
                  }
                },
                "recentValues": {
                  "default": [],
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "parentId": {
                        "type": "string",
                        "nullable": true
                      },
                      "code": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "active": {
                        "type": "boolean"
                      },
                      "sortOrder": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "path": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "defaultBillable": {
                        "type": "boolean",
                        "default": null,
                        "nullable": true
                      },
                      "customerName": {
                        "type": "string",
                        "default": null,
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "parentId",
                      "code",
                      "name",
                      "active",
                      "sortOrder"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "required",
                "active",
                "locked",
                "sortOrder",
                "values"
              ]
            }
          }
        },
        "required": [
          "dimensions"
        ]
      },
      "CustomerPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "businessId": {
                  "type": "string",
                  "nullable": true
                },
                "einvoiceAddress": {
                  "type": "string",
                  "nullable": true
                },
                "einvoiceOperator": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceReference": {
                  "type": "string",
                  "nullable": true
                },
                "billingRoundingMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "projectCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "streetAddress": {
                  "type": "string",
                  "nullable": true
                },
                "postalCode": {
                  "type": "string",
                  "nullable": true
                },
                "city": {
                  "type": "string",
                  "nullable": true
                },
                "country": {
                  "type": "string",
                  "nullable": true
                },
                "website": {
                  "type": "string",
                  "nullable": true
                },
                "industryCode": {
                  "type": "string",
                  "nullable": true
                },
                "notes": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "defaultContactId": {
                  "type": "string",
                  "nullable": true
                },
                "vatId": {
                  "type": "string",
                  "nullable": true
                },
                "vatTreatment": {
                  "type": "string",
                  "enum": [
                    "standard",
                    "reverse_charge_construction",
                    "tax_exempt"
                  ]
                },
                "invoiceEmail": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceLanguage": {
                  "type": "string",
                  "enum": [
                    "fi",
                    "sv",
                    "en",
                    null
                  ],
                  "nullable": true
                },
                "deliveryMethod": {
                  "type": "string",
                  "enum": [
                    "einvoice",
                    "email",
                    "manual",
                    null
                  ],
                  "nullable": true
                },
                "defaultPaymentTermDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "buyerReferenceDefault": {
                  "type": "string",
                  "nullable": true
                },
                "invoicingNotes": {
                  "type": "string",
                  "nullable": true
                },
                "fixedReferenceNumber": {
                  "type": "string",
                  "nullable": true
                },
                "paymentTermId": {
                  "type": "string",
                  "nullable": true
                },
                "paymentTermName": {
                  "type": "string",
                  "nullable": true
                },
                "openDealCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "openPipelineValueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "lastActivityAt": {
                  "type": "string",
                  "nullable": true
                },
                "tags": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "color": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "name",
                      "color"
                    ]
                  }
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "code",
                "name",
                "businessId",
                "einvoiceAddress",
                "einvoiceOperator",
                "invoiceReference",
                "billingRoundingMinutes",
                "active",
                "sortOrder",
                "projectCount",
                "streetAddress",
                "postalCode",
                "city",
                "country",
                "website",
                "industryCode",
                "notes",
                "ownerMembershipId",
                "defaultContactId",
                "vatId",
                "vatTreatment",
                "invoiceEmail",
                "invoiceLanguage",
                "deliveryMethod",
                "defaultPaymentTermDays",
                "buyerReferenceDefault",
                "invoicingNotes",
                "openDealCount",
                "openPipelineValueCents",
                "lastActivityAt",
                "tags",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CustomerGetResponseDto": {
        "type": "object",
        "properties": {
          "customer": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "businessId": {
                "type": "string",
                "nullable": true
              },
              "einvoiceAddress": {
                "type": "string",
                "nullable": true
              },
              "einvoiceOperator": {
                "type": "string",
                "nullable": true
              },
              "invoiceReference": {
                "type": "string",
                "nullable": true
              },
              "billingRoundingMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "active": {
                "type": "boolean"
              },
              "sortOrder": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "projectCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "streetAddress": {
                "type": "string",
                "nullable": true
              },
              "postalCode": {
                "type": "string",
                "nullable": true
              },
              "city": {
                "type": "string",
                "nullable": true
              },
              "country": {
                "type": "string",
                "nullable": true
              },
              "website": {
                "type": "string",
                "nullable": true
              },
              "industryCode": {
                "type": "string",
                "nullable": true
              },
              "notes": {
                "type": "string",
                "nullable": true
              },
              "ownerMembershipId": {
                "type": "string",
                "nullable": true
              },
              "defaultContactId": {
                "type": "string",
                "nullable": true
              },
              "vatId": {
                "type": "string",
                "nullable": true
              },
              "vatTreatment": {
                "type": "string",
                "enum": [
                  "standard",
                  "reverse_charge_construction",
                  "tax_exempt"
                ]
              },
              "invoiceEmail": {
                "type": "string",
                "nullable": true
              },
              "invoiceLanguage": {
                "type": "string",
                "enum": [
                  "fi",
                  "sv",
                  "en",
                  null
                ],
                "nullable": true
              },
              "deliveryMethod": {
                "type": "string",
                "enum": [
                  "einvoice",
                  "email",
                  "manual",
                  null
                ],
                "nullable": true
              },
              "defaultPaymentTermDays": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "buyerReferenceDefault": {
                "type": "string",
                "nullable": true
              },
              "invoicingNotes": {
                "type": "string",
                "nullable": true
              },
              "fixedReferenceNumber": {
                "type": "string",
                "nullable": true
              },
              "paymentTermId": {
                "type": "string",
                "nullable": true
              },
              "paymentTermName": {
                "type": "string",
                "nullable": true
              },
              "openDealCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "openPipelineValueCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "lastActivityAt": {
                "type": "string",
                "nullable": true
              },
              "tags": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "color": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "color"
                  ]
                }
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "code",
              "name",
              "businessId",
              "einvoiceAddress",
              "einvoiceOperator",
              "invoiceReference",
              "billingRoundingMinutes",
              "active",
              "sortOrder",
              "projectCount",
              "streetAddress",
              "postalCode",
              "city",
              "country",
              "website",
              "industryCode",
              "notes",
              "ownerMembershipId",
              "defaultContactId",
              "vatId",
              "vatTreatment",
              "invoiceEmail",
              "invoiceLanguage",
              "deliveryMethod",
              "defaultPaymentTermDays",
              "buyerReferenceDefault",
              "invoicingNotes",
              "openDealCount",
              "openPipelineValueCents",
              "lastActivityAt",
              "tags",
              "updatedAt"
            ]
          }
        },
        "required": [
          "customer"
        ]
      },
      "CreateCustomerDto": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "businessId": {
            "type": "string",
            "maxLength": 20
          },
          "einvoiceAddress": {
            "type": "string",
            "maxLength": 50
          },
          "einvoiceOperator": {
            "type": "string",
            "maxLength": 50
          },
          "invoiceReference": {
            "type": "string",
            "maxLength": 50
          },
          "billingRoundingMinutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 480
          },
          "sortOrder": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "streetAddress": {
            "type": "string",
            "maxLength": 200
          },
          "postalCode": {
            "type": "string",
            "maxLength": 20
          },
          "city": {
            "type": "string",
            "maxLength": 100
          },
          "country": {
            "type": "string",
            "maxLength": 2
          },
          "website": {
            "type": "string",
            "maxLength": 200
          },
          "industryCode": {
            "type": "string",
            "maxLength": 20
          },
          "notes": {
            "type": "string",
            "maxLength": 8000
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "defaultContactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "vatId": {
            "type": "string",
            "maxLength": 20
          },
          "vatTreatment": {
            "type": "string",
            "enum": [
              "standard",
              "reverse_charge_construction",
              "tax_exempt"
            ]
          },
          "invoiceEmail": {
            "type": "string",
            "maxLength": 320,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "invoiceLanguage": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "deliveryMethod": {
            "type": "string",
            "enum": [
              "einvoice",
              "email",
              "manual"
            ]
          },
          "defaultPaymentTermDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 90
          },
          "buyerReferenceDefault": {
            "type": "string",
            "maxLength": 70
          },
          "invoicingNotes": {
            "type": "string",
            "maxLength": 2000
          },
          "fixedReferenceNumber": {
            "type": "string",
            "pattern": "^\\d{4,20}$"
          },
          "paymentTermId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "code",
          "name"
        ]
      },
      "CustomerIdResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "UpdateCustomerDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "businessId": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "einvoiceAddress": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "einvoiceOperator": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "invoiceReference": {
            "type": "string",
            "maxLength": 50,
            "nullable": true
          },
          "billingRoundingMinutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 480,
            "nullable": true
          },
          "active": {
            "type": "boolean"
          },
          "sortOrder": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "streetAddress": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "city": {
            "type": "string",
            "maxLength": 100,
            "nullable": true
          },
          "country": {
            "type": "string",
            "maxLength": 2,
            "nullable": true
          },
          "website": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "industryCode": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "notes": {
            "type": "string",
            "maxLength": 8000,
            "nullable": true
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "defaultContactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "vatId": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "vatTreatment": {
            "type": "string",
            "enum": [
              "standard",
              "reverse_charge_construction",
              "tax_exempt"
            ]
          },
          "invoiceEmail": {
            "type": "string",
            "maxLength": 320,
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "nullable": true
          },
          "invoiceLanguage": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en",
              null
            ],
            "nullable": true
          },
          "deliveryMethod": {
            "type": "string",
            "enum": [
              "einvoice",
              "email",
              "manual",
              null
            ],
            "nullable": true
          },
          "defaultPaymentTermDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 90,
            "nullable": true
          },
          "buyerReferenceDefault": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "invoicingNotes": {
            "type": "string",
            "maxLength": 2000,
            "nullable": true
          },
          "fixedReferenceNumber": {
            "type": "string",
            "pattern": "^\\d{4,20}$",
            "nullable": true
          },
          "paymentTermId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "CustomerOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "EmploymentResponseDto": {
        "type": "object",
        "properties": {
          "employment": {
            "type": "object",
            "properties": {
              "jobTitle": {
                "type": "string",
                "nullable": true
              },
              "employmentType": {
                "type": "string",
                "enum": [
                  "permanent",
                  "fixed_term"
                ]
              },
              "fixedTermGrounds": {
                "type": "string",
                "nullable": true
              },
              "fixedTermEndDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "nullable": true
              },
              "probationEndDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "nullable": true
              },
              "payType": {
                "type": "string",
                "enum": [
                  "monthly",
                  "hourly"
                ]
              },
              "contractWeeklyMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "contractMinWeeklyMinutes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "placeOfWork": {
                "type": "string",
                "nullable": true
              },
              "placeOfWorkKind": {
                "type": "string",
                "enum": [
                  "fixed",
                  "varying",
                  "remote",
                  "no_fixed"
                ]
              },
              "employerId": {
                "type": "string",
                "nullable": true
              },
              "employerName": {
                "type": "string",
                "nullable": true
              },
              "payGroup": {
                "type": "string",
                "nullable": true
              },
              "payrollNumber": {
                "type": "string",
                "nullable": true
              },
              "pensionProvider": {
                "type": "string",
                "nullable": true
              },
              "accidentInsurer": {
                "type": "string",
                "nullable": true
              },
              "leaveAccrualRule": {
                "type": "string",
                "enum": [
                  "14-day",
                  "35-hour",
                  null
                ],
                "nullable": true
              },
              "terminationReason": {
                "type": "string",
                "nullable": true
              },
              "terminationNoticeDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "nullable": true
              },
              "fixedTermRenewalCount": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "jobTitle",
              "employmentType",
              "fixedTermGrounds",
              "fixedTermEndDate",
              "probationEndDate",
              "payType",
              "contractWeeklyMinutes",
              "contractMinWeeklyMinutes",
              "placeOfWork",
              "placeOfWorkKind",
              "employerId",
              "employerName",
              "payGroup",
              "payrollNumber",
              "pensionProvider",
              "accidentInsurer",
              "leaveAccrualRule",
              "terminationReason",
              "terminationNoticeDate",
              "fixedTermRenewalCount"
            ]
          }
        },
        "required": [
          "employment"
        ]
      },
      "UpdateEmploymentDto": {
        "type": "object",
        "properties": {
          "jobTitle": {
            "type": "string",
            "maxLength": 120,
            "nullable": true
          },
          "employmentType": {
            "type": "string",
            "enum": [
              "permanent",
              "fixed_term"
            ]
          },
          "fixedTermGrounds": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          },
          "fixedTermEndDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "probationEndDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "payType": {
            "type": "string",
            "enum": [
              "monthly",
              "hourly"
            ]
          },
          "payrollNumber": {
            "type": "string",
            "maxLength": 40,
            "nullable": true
          },
          "pensionProvider": {
            "type": "string",
            "maxLength": 120,
            "nullable": true
          },
          "accidentInsurer": {
            "type": "string",
            "maxLength": 120,
            "nullable": true
          },
          "leaveAccrualRule": {
            "type": "string",
            "enum": [
              "14-day",
              "35-hour",
              null
            ],
            "nullable": true
          },
          "employerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        },
        "required": [
          "employmentType",
          "payType"
        ]
      },
      "EmploymentOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "PayrollIdentityViewDto": {
        "type": "object",
        "properties": {
          "membershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "displayName": {
            "type": "string"
          },
          "payrollNumber": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "membershipId",
          "displayName",
          "payrollNumber"
        ]
      },
      "UpdatePayrollIdentityDto": {
        "type": "object",
        "properties": {
          "payrollNumber": {
            "type": "string",
            "maxLength": 40,
            "nullable": true
          }
        },
        "required": [
          "payrollNumber"
        ]
      },
      "TerminationResponseDto": {
        "type": "object",
        "properties": {
          "termination": {
            "type": "object",
            "properties": {
              "active": {
                "type": "boolean"
              },
              "endDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "nullable": true
              },
              "reasonCode": {
                "type": "string",
                "enum": [
                  "resignation",
                  "termination_person",
                  "termination_finance",
                  "fixed_term_end",
                  "probation_cancellation",
                  "rescission",
                  "retirement",
                  "mutual_agreement",
                  "other",
                  null
                ],
                "nullable": true
              },
              "noticeDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "nullable": true
              },
              "note": {
                "type": "string",
                "nullable": true
              },
              "offboardingRunId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                "nullable": true
              },
              "noticeDefaults": {
                "type": "object",
                "properties": {
                  "serviceDays": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "employer": {
                    "type": "object",
                    "properties": {
                      "unit": {
                        "type": "string",
                        "enum": [
                          "days",
                          "months"
                        ]
                      },
                      "value": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "maximum": 9007199254740991,
                        "minimum": 0
                      }
                    },
                    "required": [
                      "unit",
                      "value"
                    ]
                  },
                  "employee": {
                    "type": "object",
                    "properties": {
                      "unit": {
                        "type": "string",
                        "enum": [
                          "days",
                          "months"
                        ]
                      },
                      "value": {
                        "type": "integer",
                        "exclusiveMinimum": true,
                        "maximum": 9007199254740991,
                        "minimum": 0
                      }
                    },
                    "required": [
                      "unit",
                      "value"
                    ]
                  },
                  "earliestEndDateEmployer": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  },
                  "earliestEndDateEmployee": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                  }
                },
                "required": [
                  "serviceDays",
                  "employer",
                  "employee",
                  "earliestEndDateEmployer",
                  "earliestEndDateEmployee"
                ],
                "nullable": true
              }
            },
            "required": [
              "active",
              "endDate",
              "reasonCode",
              "noticeDate",
              "note",
              "offboardingRunId",
              "noticeDefaults"
            ]
          }
        },
        "required": [
          "termination"
        ]
      },
      "TerminateEmploymentDto": {
        "type": "object",
        "properties": {
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "reasonCode": {
            "type": "string",
            "enum": [
              "resignation",
              "termination_person",
              "termination_finance",
              "fixed_term_end",
              "probation_cancellation",
              "rescission",
              "retirement",
              "mutual_agreement",
              "other"
            ]
          },
          "noticeDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "note": {
            "type": "string",
            "maxLength": 2000,
            "nullable": true
          },
          "startOffboarding": {
            "type": "boolean"
          },
          "offboardingTemplateId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        },
        "required": [
          "endDate",
          "reasonCode",
          "startOffboarding"
        ]
      },
      "AbsencePolicyListResponseDto": {
        "type": "object",
        "properties": {
          "policies": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "dayTypeId": {
                  "type": "string"
                },
                "dayTypeCode": {
                  "type": "string"
                },
                "partialEntryTypeId": {
                  "type": "string",
                  "nullable": true
                },
                "workflowMode": {
                  "type": "string",
                  "enum": [
                    "request",
                    "notification",
                    "employer_assignment"
                  ]
                },
                "sensitivity": {
                  "type": "string",
                  "enum": [
                    "normal",
                    "restricted",
                    "health"
                  ]
                },
                "availabilityEffect": {
                  "type": "string",
                  "enum": [
                    "unavailable",
                    "none"
                  ]
                },
                "consumesLeaveLedgerKind": {
                  "type": "string",
                  "enum": [
                    "annual_leave",
                    "additional_leave",
                    "free_time",
                    "saved_leave",
                    "bonus_leave",
                    null
                  ],
                  "nullable": true
                },
                "consumesAccount": {
                  "type": "object",
                  "properties": {
                    "accountTypeId": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "flex",
                        "overtime_bank",
                        "worktime_bank",
                        "shorter_worktime"
                      ]
                    },
                    "code": {
                      "type": "string"
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "accountTypeId",
                    "kind",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn"
                  ],
                  "default": null,
                  "nullable": true
                },
                "requiresApproval": {
                  "type": "boolean"
                },
                "certificateAfterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "default": null,
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "dayTypeId",
                "dayTypeCode",
                "partialEntryTypeId",
                "workflowMode",
                "sensitivity",
                "availabilityEffect",
                "consumesLeaveLedgerKind",
                "requiresApproval",
                "active",
                "sortOrder"
              ]
            }
          },
          "approver": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "nullable": true
          }
        },
        "required": [
          "policies"
        ]
      },
      "AbsencePeriodListResponseDto": {
        "type": "object",
        "properties": {
          "periods": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "membershipId": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string",
                  "nullable": true
                },
                "policyId": {
                  "type": "string"
                },
                "policyCode": {
                  "type": "string"
                },
                "policyNameFi": {
                  "type": "string"
                },
                "policyNameSv": {
                  "type": "string"
                },
                "policyNameEn": {
                  "type": "string"
                },
                "sensitivity": {
                  "type": "string",
                  "enum": [
                    "normal",
                    "restricted",
                    "health"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "submitted",
                    "approved",
                    "rejected",
                    "cancelled",
                    "withdrawn"
                  ]
                },
                "origin": {
                  "type": "string",
                  "enum": [
                    "employee",
                    "planner"
                  ]
                },
                "workflowMode": {
                  "type": "string",
                  "enum": [
                    "request",
                    "notification",
                    "employer_assignment"
                  ]
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "startHalfDay": {
                  "type": "boolean"
                },
                "endHalfDay": {
                  "type": "boolean"
                },
                "consumesQuarterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "consumesMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "certificateRequired": {
                  "default": false,
                  "type": "boolean"
                },
                "certificateStatus": {
                  "type": "string",
                  "enum": [
                    "missing",
                    "provided",
                    "waived",
                    null
                  ],
                  "default": null,
                  "nullable": true
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                },
                "decidedByMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "decidedByName": {
                  "type": "string",
                  "nullable": true
                },
                "decidedAt": {
                  "type": "string",
                  "nullable": true
                },
                "decisionReason": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                },
                "viewerPermissions": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "viewCapacity",
                      "viewAbsenceDetail",
                      "requestForSelf",
                      "decideLeave",
                      "administerEntitlement"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "membershipId",
                "memberName",
                "policyId",
                "policyCode",
                "policyNameFi",
                "policyNameSv",
                "policyNameEn",
                "sensitivity",
                "status",
                "origin",
                "workflowMode",
                "startDate",
                "endDate",
                "startHalfDay",
                "endHalfDay",
                "consumesQuarterDays",
                "reason",
                "decidedByMembershipId",
                "decidedByName",
                "decidedAt",
                "decisionReason",
                "createdAt",
                "updatedAt",
                "viewerPermissions"
              ]
            }
          }
        },
        "required": [
          "periods"
        ]
      },
      "PreviewAbsencePeriodDto": {
        "type": "object",
        "properties": {
          "policyId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "startHalfDay": {
            "type": "boolean"
          },
          "endHalfDay": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "maxLength": 1000
          },
          "excludePeriodId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "policyId",
          "startDate",
          "endDate"
        ]
      },
      "AbsencePeriodPreviewDto": {
        "type": "object",
        "properties": {
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "available": {
                  "type": "boolean"
                },
                "workRecordForm": {
                  "type": "string",
                  "enum": [
                    "none",
                    "day_type",
                    "entry_type"
                  ]
                },
                "expectedTargetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "expectedSource": {
                  "type": "string",
                  "nullable": true
                },
                "consumesEntitlement": {
                  "type": "boolean"
                },
                "consumesQuarterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "consumesAccountMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "exclusionReason": {
                  "type": "string",
                  "enum": [
                    "consumes",
                    "sunday",
                    "rest-day",
                    "exception-day",
                    "public-holiday",
                    "eve",
                    "easter-saturday",
                    "not-leave-policy",
                    "not-workday"
                  ]
                },
                "sickWaitingDay": {
                  "default": false,
                  "type": "boolean"
                },
                "sickPayInfo": {
                  "type": "object",
                  "properties": {
                    "paid": {
                      "type": "boolean"
                    },
                    "percent": {
                      "type": "number"
                    },
                    "paidDayIndex": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    }
                  },
                  "required": [
                    "paid",
                    "percent",
                    "paidDayIndex"
                  ],
                  "default": null,
                  "nullable": true
                }
              },
              "required": [
                "workDate",
                "available",
                "workRecordForm",
                "expectedTargetMinutes",
                "expectedSource",
                "consumesEntitlement",
                "consumesQuarterDays",
                "exclusionReason"
              ]
            }
          },
          "consumesQuarterDays": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "consumesDays": {
            "type": "number"
          },
          "consumesAccountMinutes": {
            "default": 0,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "bankBalanceSource": {
            "type": "object",
            "properties": {
              "account": {
                "type": "object",
                "properties": {
                  "accountTypeId": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "flex",
                      "overtime_bank",
                      "worktime_bank",
                      "shorter_worktime"
                    ]
                  },
                  "code": {
                    "type": "string"
                  },
                  "nameFi": {
                    "type": "string"
                  },
                  "nameSv": {
                    "type": "string"
                  },
                  "nameEn": {
                    "type": "string"
                  }
                },
                "required": [
                  "accountTypeId",
                  "kind",
                  "code",
                  "nameFi",
                  "nameSv",
                  "nameEn"
                ]
              },
              "settledMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "plannedDrawMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "floorMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "availableMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "allowAdvance": {
                "type": "boolean"
              }
            },
            "required": [
              "account",
              "settledMinutes",
              "plannedDrawMinutes",
              "floorMinutes",
              "availableMinutes",
              "allowAdvance"
            ],
            "default": null,
            "nullable": true
          },
          "blockingErrors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "conflicts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "existing-draft",
                    "confirmed-day",
                    "exported-day",
                    "published-shift",
                    "overlapping-period",
                    "outside-employment"
                  ]
                }
              },
              "required": [
                "workDate",
                "type"
              ]
            }
          },
          "recordedDayBlocks": {
            "default": [],
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "confirmed",
                    "approved"
                  ]
                },
                "canReopen": {
                  "type": "boolean"
                },
                "reopenBlockedReason": {
                  "type": "string",
                  "enum": [
                    "requires_supervisor",
                    "period_locked",
                    "day_invoiced",
                    null
                  ],
                  "default": null,
                  "nullable": true
                }
              },
              "required": [
                "workDate",
                "status",
                "canReopen"
              ]
            }
          }
        },
        "required": [
          "days",
          "consumesQuarterDays",
          "consumesDays",
          "blockingErrors",
          "warnings",
          "conflicts"
        ]
      },
      "CreateAbsencePeriodDto": {
        "type": "object",
        "properties": {
          "policyId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "startHalfDay": {
            "type": "boolean"
          },
          "endHalfDay": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "policyId",
          "startDate",
          "endDate"
        ]
      },
      "AbsencePeriodDetailDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "membershipId": {
            "type": "string"
          },
          "memberName": {
            "type": "string",
            "nullable": true
          },
          "policyId": {
            "type": "string"
          },
          "policyCode": {
            "type": "string"
          },
          "policyNameFi": {
            "type": "string"
          },
          "policyNameSv": {
            "type": "string"
          },
          "policyNameEn": {
            "type": "string"
          },
          "sensitivity": {
            "type": "string",
            "enum": [
              "normal",
              "restricted",
              "health"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "submitted",
              "approved",
              "rejected",
              "cancelled",
              "withdrawn"
            ]
          },
          "origin": {
            "type": "string",
            "enum": [
              "employee",
              "planner"
            ]
          },
          "workflowMode": {
            "type": "string",
            "enum": [
              "request",
              "notification",
              "employer_assignment"
            ]
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "startHalfDay": {
            "type": "boolean"
          },
          "endHalfDay": {
            "type": "boolean"
          },
          "consumesQuarterDays": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "consumesMinutes": {
            "default": 0,
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "certificateRequired": {
            "default": false,
            "type": "boolean"
          },
          "certificateStatus": {
            "type": "string",
            "enum": [
              "missing",
              "provided",
              "waived",
              null
            ],
            "default": null,
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "decidedByMembershipId": {
            "type": "string",
            "nullable": true
          },
          "decidedByName": {
            "type": "string",
            "nullable": true
          },
          "decidedAt": {
            "type": "string",
            "nullable": true
          },
          "decisionReason": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "viewerPermissions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "viewCapacity",
                "viewAbsenceDetail",
                "requestForSelf",
                "decideLeave",
                "administerEntitlement"
              ]
            }
          },
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "available": {
                  "type": "boolean"
                },
                "workRecordForm": {
                  "type": "string",
                  "enum": [
                    "none",
                    "day_type",
                    "entry_type"
                  ]
                },
                "expectedTargetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "expectedSource": {
                  "type": "string",
                  "nullable": true
                },
                "consumesEntitlement": {
                  "type": "boolean"
                },
                "consumesQuarterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "consumesAccountMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "exclusionReason": {
                  "type": "string",
                  "enum": [
                    "consumes",
                    "sunday",
                    "rest-day",
                    "exception-day",
                    "public-holiday",
                    "eve",
                    "easter-saturday",
                    "not-leave-policy",
                    "not-workday"
                  ]
                },
                "sickWaitingDay": {
                  "default": false,
                  "type": "boolean"
                },
                "sickPayInfo": {
                  "type": "object",
                  "properties": {
                    "paid": {
                      "type": "boolean"
                    },
                    "percent": {
                      "type": "number"
                    },
                    "paidDayIndex": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "nullable": true
                    }
                  },
                  "required": [
                    "paid",
                    "percent",
                    "paidDayIndex"
                  ],
                  "default": null,
                  "nullable": true
                }
              },
              "required": [
                "workDate",
                "available",
                "workRecordForm",
                "expectedTargetMinutes",
                "expectedSource",
                "consumesEntitlement",
                "consumesQuarterDays",
                "exclusionReason"
              ]
            }
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "submit",
                    "approve",
                    "reject",
                    "withdraw",
                    "cancel",
                    "postpone",
                    "modify",
                    "restore",
                    "certificate_provided",
                    "certificate_waived",
                    "certificate_reset"
                  ]
                },
                "actorMembershipId": {
                  "type": "string"
                },
                "actorName": {
                  "type": "string"
                },
                "occurredAt": {
                  "type": "string"
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "type",
                "actorMembershipId",
                "actorName",
                "occurredAt",
                "reason"
              ]
            }
          },
          "comments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "authorMembershipId": {
                  "type": "string"
                },
                "authorName": {
                  "type": "string"
                },
                "body": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "authorMembershipId",
                "authorName",
                "body",
                "createdAt"
              ]
            }
          },
          "conflicts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "existing-draft",
                    "confirmed-day",
                    "exported-day",
                    "published-shift",
                    "overlapping-period",
                    "outside-employment"
                  ]
                }
              },
              "required": [
                "workDate",
                "type"
              ]
            }
          },
          "planningUnitId": {
            "type": "string",
            "nullable": true
          },
          "consumesLeaveLedgerKind": {
            "type": "string",
            "enum": [
              "annual_leave",
              "additional_leave",
              "free_time",
              "saved_leave",
              "bonus_leave",
              null
            ],
            "nullable": true
          }
        },
        "required": [
          "id",
          "membershipId",
          "memberName",
          "policyId",
          "policyCode",
          "policyNameFi",
          "policyNameSv",
          "policyNameEn",
          "sensitivity",
          "status",
          "origin",
          "workflowMode",
          "startDate",
          "endDate",
          "startHalfDay",
          "endHalfDay",
          "consumesQuarterDays",
          "reason",
          "decidedByMembershipId",
          "decidedByName",
          "decidedAt",
          "decisionReason",
          "createdAt",
          "updatedAt",
          "viewerPermissions",
          "days",
          "events",
          "comments",
          "conflicts",
          "planningUnitId",
          "consumesLeaveLedgerKind"
        ]
      },
      "SubmitAbsencePeriodDto": {
        "type": "object",
        "properties": {
          "reopenRecordedDays": {
            "type": "boolean"
          }
        },
        "default": {}
      },
      "ApproveAbsencePeriodDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500
          },
          "expectedUpdatedAt": {
            "type": "string"
          },
          "reopenRecordedDays": {
            "type": "boolean"
          }
        }
      },
      "TeamAbsenceResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "periods": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "startDate": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "endDate": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "draft",
                          "submitted",
                          "approved",
                          "rejected",
                          "cancelled",
                          "withdrawn"
                        ]
                      },
                      "updatedAt": {
                        "type": "string"
                      },
                      "workflowMode": {
                        "type": "string",
                        "enum": [
                          "request",
                          "notification",
                          "employer_assignment"
                        ]
                      },
                      "detail": {
                        "type": "object",
                        "properties": {
                          "policyCode": {
                            "type": "string"
                          },
                          "policyNameFi": {
                            "type": "string"
                          },
                          "policyNameSv": {
                            "type": "string"
                          },
                          "policyNameEn": {
                            "type": "string"
                          },
                          "consumesQuarterDays": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "consumesLeaveLedgerKind": {
                            "type": "string",
                            "enum": [
                              "annual_leave",
                              "additional_leave",
                              "free_time",
                              "saved_leave",
                              "bonus_leave",
                              null
                            ],
                            "nullable": true
                          }
                        },
                        "required": [
                          "policyCode",
                          "policyNameFi",
                          "policyNameSv",
                          "policyNameEn",
                          "consumesQuarterDays",
                          "consumesLeaveLedgerKind"
                        ],
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "startDate",
                      "endDate",
                      "status",
                      "updatedAt",
                      "workflowMode",
                      "detail"
                    ]
                  }
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "periods"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          },
          "blackouts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "blackout",
                    "wish_window"
                  ]
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "planningUnitId": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "kind",
                "nameFi",
                "nameSv",
                "nameEn",
                "startDate",
                "endDate",
                "planningUnitId"
              ]
            }
          }
        },
        "required": [
          "items",
          "pageInfo",
          "blackouts"
        ]
      },
      "RejectAbsencePeriodDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "reason"
        ]
      },
      "PlanAbsencePeriodDto": {
        "type": "object",
        "properties": {
          "policyId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "startHalfDay": {
            "type": "boolean"
          },
          "endHalfDay": {
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "maxLength": 1000
          },
          "membershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "excludePeriodId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "reopenRecordedDays": {
            "type": "boolean"
          }
        },
        "required": [
          "policyId",
          "startDate",
          "endDate",
          "membershipId"
        ]
      },
      "LeaveBalanceResponseDto": {
        "type": "object",
        "properties": {
          "membershipId": {
            "type": "string"
          },
          "asOf": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "creditYearEnd": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "balances": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "ledgerKind": {
                  "type": "string",
                  "enum": [
                    "annual_leave",
                    "additional_leave",
                    "free_time",
                    "saved_leave",
                    "bonus_leave"
                  ]
                },
                "quarterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "days": {
                  "type": "number"
                },
                "recordedQuarterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "recordedDays": {
                  "type": "number"
                },
                "projectedQuarterDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "projectedDays": {
                  "type": "number"
                }
              },
              "required": [
                "ledgerKind",
                "quarterDays",
                "days",
                "recordedQuarterDays",
                "recordedDays",
                "projectedQuarterDays",
                "projectedDays"
              ]
            }
          },
          "saveableQuarterDays": {
            "default": 0,
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "saveableDays": {
            "default": 0,
            "type": "number",
            "minimum": 0
          }
        },
        "required": [
          "membershipId",
          "asOf",
          "creditYearEnd",
          "balances"
        ]
      },
      "LeaveSaveProposalOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "ApproveLeaveSaveProposalDto": {
        "type": "object",
        "properties": {
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "DeclineLeaveSaveProposalDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "reason"
        ]
      },
      "MembershipListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "employee",
                    "manager",
                    "admin",
                    "payroll",
                    "hr"
                  ]
                },
                "managerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "worktimeModelId": {
                  "type": "string",
                  "nullable": true
                },
                "planningUnitId": {
                  "type": "string",
                  "nullable": true
                },
                "canPlanAllUnits": {
                  "type": "boolean"
                },
                "active": {
                  "type": "boolean"
                },
                "employmentStartDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "employmentEndDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "personalFlexMinMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "personalFlexMaxMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "employer": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "name"
                  ],
                  "nullable": true
                },
                "invitationStatus": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "accepted",
                    "expired",
                    null
                  ],
                  "nullable": true
                },
                "jobTitle": {
                  "type": "string",
                  "nullable": true
                },
                "fixedTermEndDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "attention": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "statement_due",
                      "statement_update_due",
                      "probation_review",
                      "fixed_term_ending",
                      "qualification_expiring",
                      "qualification_expired"
                    ]
                  },
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "displayName",
                "email",
                "role",
                "managerMembershipId",
                "worktimeModelId",
                "planningUnitId",
                "canPlanAllUnits",
                "active",
                "employmentStartDate",
                "employmentEndDate",
                "personalFlexMinMinutes",
                "personalFlexMaxMinutes",
                "employer",
                "invitationStatus",
                "jobTitle",
                "fixedTermEndDate",
                "attention",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "MembershipDetailResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "employee",
              "manager",
              "admin",
              "payroll",
              "hr"
            ]
          },
          "managerMembershipId": {
            "type": "string",
            "nullable": true
          },
          "worktimeModelId": {
            "type": "string",
            "nullable": true
          },
          "planningUnitId": {
            "type": "string",
            "nullable": true
          },
          "canPlanAllUnits": {
            "type": "boolean"
          },
          "active": {
            "type": "boolean"
          },
          "employmentStartDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "employmentEndDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "personalFlexMinMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "personalFlexMaxMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "employer": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "nullable": true
          },
          "invitationStatus": {
            "type": "string",
            "enum": [
              "pending",
              "accepted",
              "expired",
              null
            ],
            "nullable": true
          },
          "jobTitle": {
            "type": "string",
            "nullable": true
          },
          "fixedTermEndDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "attention": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "statement_due",
                "statement_update_due",
                "probation_review",
                "fixed_term_ending",
                "qualification_expiring",
                "qualification_expired"
              ]
            },
            "nullable": true
          },
          "updatedAt": {
            "type": "string"
          },
          "managerName": {
            "type": "string",
            "nullable": true
          },
          "units": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "planningUnitId": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "isPrimary": {
                  "type": "boolean"
                },
                "validFrom": {
                  "type": "string"
                }
              },
              "required": [
                "planningUnitId",
                "name",
                "isPrimary",
                "validFrom"
              ]
            }
          },
          "leaveGroupId": {
            "type": "string",
            "nullable": true
          },
          "preferredLanguage": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en",
              null
            ],
            "nullable": true
          },
          "isMinor": {
            "type": "boolean"
          },
          "hrScopeUnitIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "hrRecorder": {
            "type": "boolean"
          },
          "crmSeat": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "displayName",
          "email",
          "role",
          "managerMembershipId",
          "worktimeModelId",
          "planningUnitId",
          "canPlanAllUnits",
          "active",
          "employmentStartDate",
          "employmentEndDate",
          "personalFlexMinMinutes",
          "personalFlexMaxMinutes",
          "employer",
          "invitationStatus",
          "jobTitle",
          "fixedTermEndDate",
          "attention",
          "updatedAt",
          "managerName",
          "units",
          "leaveGroupId",
          "preferredLanguage",
          "isMinor",
          "hrScopeUnitIds",
          "hrRecorder",
          "crmSeat"
        ]
      },
      "CreateMembershipDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "displayName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "role": {
            "type": "string",
            "enum": [
              "employee",
              "manager",
              "admin",
              "payroll",
              "hr"
            ]
          },
          "phone": {
            "type": "string",
            "maxLength": 40
          },
          "managerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "worktimeModelId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "leaveGroupId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "initialPassword": {
            "type": "string",
            "minLength": 10,
            "maxLength": 200
          },
          "locale": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "moduleAccess": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "shift_planning",
                "travel_expense",
                "hr",
                "project_management",
                "crm"
              ]
            }
          }
        },
        "required": [
          "displayName",
          "role"
        ]
      },
      "CreateMembershipResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "invitation": {
            "type": "object",
            "properties": {
              "inviteUrl": {
                "type": "string"
              },
              "emailed": {
                "type": "boolean"
              },
              "expiresAt": {
                "type": "string"
              }
            },
            "required": [
              "inviteUrl",
              "emailed",
              "expiresAt"
            ],
            "nullable": true
          },
          "moduleGrants": {
            "type": "object",
            "properties": {
              "granted": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "shift_planning",
                    "travel_expense",
                    "hr",
                    "project_management",
                    "crm"
                  ]
                }
              },
              "seatLimited": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "shift_planning",
                    "travel_expense",
                    "hr",
                    "project_management",
                    "crm"
                  ]
                }
              }
            },
            "required": [
              "granted",
              "seatLimited"
            ]
          }
        },
        "required": [
          "id",
          "invitation",
          "moduleGrants"
        ]
      },
      "BulkCreateMembershipsDto": {
        "type": "object",
        "properties": {
          "rows": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string",
                  "format": "email",
                  "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                },
                "displayName": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "employee",
                    "manager",
                    "admin",
                    "payroll",
                    "hr"
                  ]
                },
                "phone": {
                  "type": "string",
                  "maxLength": 40
                },
                "managerMembershipId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "managerEmail": {
                  "type": "string",
                  "format": "email",
                  "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                },
                "worktimeModelId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "unitName": {
                  "type": "string",
                  "maxLength": 200
                },
                "worktimeModelName": {
                  "type": "string",
                  "maxLength": 200
                },
                "employerCode": {
                  "type": "string",
                  "maxLength": 40
                },
                "employmentStartDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "employmentEndDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "employmentType": {
                  "type": "string",
                  "enum": [
                    "permanent",
                    "fixed_term"
                  ]
                },
                "jobTitle": {
                  "type": "string",
                  "maxLength": 120
                },
                "locale": {
                  "type": "string",
                  "enum": [
                    "fi",
                    "sv",
                    "en"
                  ]
                }
              },
              "required": [
                "displayName",
                "role"
              ]
            }
          },
          "locale": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "initialPassword": {
            "type": "string",
            "minLength": 10,
            "maxLength": 200
          },
          "moduleAccess": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "shift_planning",
                "travel_expense",
                "hr",
                "project_management",
                "crm"
              ]
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "BulkCreateMembershipsResponseDto": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "invited",
                    "created",
                    "skipped",
                    "error"
                  ]
                },
                "membershipId": {
                  "type": "string",
                  "nullable": true
                },
                "code": {
                  "type": "string",
                  "nullable": true
                },
                "grantedModules": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "shift_planning",
                      "travel_expense",
                      "hr",
                      "project_management",
                      "crm"
                    ]
                  }
                },
                "seatLimitedModules": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "shift_planning",
                      "travel_expense",
                      "hr",
                      "project_management",
                      "crm"
                    ]
                  }
                }
              },
              "required": [
                "email",
                "displayName",
                "status",
                "membershipId",
                "code",
                "grantedModules",
                "seatLimitedModules"
              ]
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "InviteMemberDto": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          }
        }
      },
      "MembershipInviteResultDto": {
        "type": "object",
        "properties": {
          "inviteUrl": {
            "type": "string"
          },
          "emailed": {
            "type": "boolean"
          },
          "expiresAt": {
            "type": "string"
          }
        },
        "required": [
          "inviteUrl",
          "emailed",
          "expiresAt"
        ]
      },
      "UpdateMembershipDto": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "employee",
              "manager",
              "admin",
              "payroll",
              "hr"
            ]
          },
          "managerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "worktimeModelId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "planningUnitId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "leaveGroupId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "canPlanAllUnits": {
            "type": "boolean"
          },
          "hrScopeUnitIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "hrRecorder": {
            "type": "boolean"
          },
          "crmSeat": {
            "type": "boolean"
          },
          "employmentStartDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "employmentEndDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "personalFlexMinMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "personalFlexMaxMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          }
        }
      },
      "MembershipOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "AddMembershipUnitDto": {
        "type": "object",
        "properties": {
          "planningUnitId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "planningUnitId"
        ]
      },
      "DeactivateMembershipResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "orphanedServiceKeys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name"
              ]
            }
          }
        },
        "required": [
          "ok",
          "orphanedServiceKeys"
        ]
      },
      "TrainingRequestOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "ApproveTrainingRequestDto": {
        "type": "object",
        "properties": {
          "expectedUpdatedAt": {
            "type": "string"
          }
        }
      },
      "DeclineTrainingRequestDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "reason"
        ]
      },
      "ProjectPortfolioAttentionResponseDto": {
        "type": "object",
        "properties": {
          "projectCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "attentionProjectCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "overBudgetCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "atRiskCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "overdueTaskCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "readyToBillCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "overdueInvoiceCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "overdueInvoiceCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "projectCount",
          "attentionProjectCount",
          "overBudgetCount",
          "atRiskCount",
          "overdueTaskCount"
        ]
      },
      "ProjectRosterResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "projectId": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "ownerMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "ownerName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "active",
                    "on_hold",
                    "closed"
                  ]
                },
                "billingModel": {
                  "type": "string",
                  "enum": [
                    "time_materials",
                    "fixed_price",
                    "non_billable",
                    "retainer"
                  ]
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "health": {
                  "type": "string",
                  "enum": [
                    "on_track",
                    "at_risk",
                    "over_budget",
                    "no_data"
                  ]
                },
                "minutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "billableMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "lifetimeMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "revenueBasis": {
                  "type": "string",
                  "enum": [
                    "worked",
                    "invoiced"
                  ]
                },
                "revenueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "contractValueCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "approvedChangeOrderCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "invoicedLifetimeCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "costCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "marginCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "marginPct": {
                  "type": "number",
                  "nullable": true
                },
                "expenseCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "expenseRevenueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "purchaseCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "purchaseRevenueCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "unpricedBillableMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "uncostedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetAmountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "budgetMinutesUsedPct": {
                  "type": "number",
                  "nullable": true
                },
                "budgetAmountUsedPct": {
                  "type": "number",
                  "nullable": true
                },
                "openTaskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "overdueTaskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "healthReasons": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "over_budget",
                      "past_end",
                      "near_budget",
                      "thin_margin",
                      "losing",
                      "tasks_overdue"
                    ]
                  }
                },
                "statusUpdate": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "rag": {
                      "type": "string",
                      "enum": [
                        "on_track",
                        "at_risk",
                        "off_track"
                      ]
                    },
                    "note": {
                      "type": "string"
                    },
                    "authorName": {
                      "type": "string",
                      "nullable": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                    }
                  },
                  "required": [
                    "id",
                    "rag",
                    "note",
                    "authorName",
                    "createdAt"
                  ],
                  "nullable": true
                },
                "situation": {
                  "type": "string",
                  "enum": [
                    "on_track",
                    "at_risk",
                    "off_track",
                    "none"
                  ]
                },
                "situationSource": {
                  "type": "string",
                  "enum": [
                    "update",
                    "computed"
                  ]
                },
                "unbilledCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                }
              },
              "required": [
                "projectId",
                "code",
                "name",
                "customerId",
                "customerName",
                "ownerMembershipId",
                "ownerName",
                "status",
                "billingModel",
                "startDate",
                "endDate",
                "health",
                "minutes",
                "billableMinutes",
                "lifetimeMinutes",
                "revenueBasis",
                "revenueCents",
                "contractValueCents",
                "approvedChangeOrderCents",
                "invoicedLifetimeCents",
                "costCents",
                "marginCents",
                "marginPct",
                "expenseCostCents",
                "expenseRevenueCents",
                "purchaseCostCents",
                "purchaseRevenueCents",
                "unpricedBillableMinutes",
                "uncostedMinutes",
                "budgetMinutes",
                "budgetAmountCents",
                "budgetMinutesUsedPct",
                "budgetAmountUsedPct",
                "openTaskCount",
                "overdueTaskCount",
                "healthReasons",
                "statusUpdate",
                "situation",
                "situationSource",
                "unbilledCents"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          },
          "includesCost": {
            "type": "boolean"
          },
          "kpis": {
            "type": "object",
            "properties": {
              "projectCount": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "totalMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalRevenueCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "avgMarginPct": {
                "type": "number",
                "nullable": true
              },
              "overBudgetCount": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "unbilledProjectCount": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "nullable": true
              }
            },
            "required": [
              "projectCount",
              "totalMinutes",
              "totalRevenueCents",
              "avgMarginPct",
              "overBudgetCount",
              "unbilledProjectCount"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo",
          "includesCost",
          "kpis"
        ]
      },
      "ProjectOverviewResponseDto": {
        "type": "object",
        "properties": {
          "attention": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "overdue",
                        "blocked",
                        "waiting"
                      ]
                    },
                    "taskId": {
                      "type": "string",
                      "nullable": true
                    },
                    "title": {
                      "type": "string"
                    },
                    "taskKey": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "kind",
                    "taskId",
                    "title",
                    "taskKey"
                  ]
                }
              },
              "more": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "items",
              "more"
            ]
          },
          "milestones": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "taskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "past": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "name",
                "date",
                "taskCount",
                "past"
              ]
            }
          },
          "completion": {
            "type": "object",
            "properties": {
              "done": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "countable": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "pct": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "earnedPct": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "spiAvailable": {
                "type": "boolean"
              }
            },
            "required": [
              "done",
              "countable",
              "pct",
              "earnedPct",
              "spiAvailable"
            ]
          },
          "budget": {
            "type": "object",
            "properties": {
              "budgetMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "lifetimeMinutes": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "budgetMinutesUsedPct": {
                "type": "number",
                "nullable": true
              },
              "budgetAmountCents": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "budgetAmountUsedPct": {
                "type": "number",
                "nullable": true
              },
              "forecast": {
                "type": "object",
                "properties": {
                  "eacMinutes": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "eacBudgetMinutesPct": {
                    "type": "number",
                    "nullable": true
                  },
                  "overBudgetMinutes": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "eacMinutes",
                  "eacBudgetMinutesPct",
                  "overBudgetMinutes"
                ],
                "nullable": true
              }
            },
            "required": [
              "budgetMinutes",
              "lifetimeMinutes",
              "budgetMinutesUsedPct",
              "budgetAmountCents",
              "budgetAmountUsedPct",
              "forecast"
            ]
          },
          "margin": {
            "type": "object",
            "properties": {
              "marginCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "marginPct": {
                "type": "number",
                "nullable": true
              },
              "tesDeltaCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              }
            },
            "required": [
              "marginCents",
              "marginPct",
              "tesDeltaCents"
            ],
            "nullable": true
          },
          "unbilled": {
            "type": "object",
            "properties": {
              "taskCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "lineCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "totalCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "unpricedLineCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "taskCount",
              "lineCount",
              "totalCents",
              "unpricedLineCount"
            ],
            "nullable": true
          },
          "team": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string"
                },
                "plannedMinutesPerWeek": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                }
              },
              "required": [
                "id",
                "memberName",
                "plannedMinutesPerWeek"
              ]
            }
          },
          "recentActivity": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "memberName": {
                  "type": "string"
                },
                "valueName": {
                  "type": "string"
                },
                "minutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "entryCount": {
                  "type": "integer",
                  "exclusiveMinimum": true,
                  "maximum": 9007199254740991,
                  "minimum": 0
                }
              },
              "required": [
                "workDate",
                "memberName",
                "valueName",
                "minutes",
                "entryCount"
              ]
            }
          },
          "feed": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "task_activity",
                    "status_update",
                    "baseline_set",
                    "approval_response",
                    "purchase_added"
                  ]
                },
                "actorName": {
                  "type": "string",
                  "nullable": true
                },
                "taskId": {
                  "type": "string",
                  "nullable": true
                },
                "taskKey": {
                  "type": "string",
                  "nullable": true
                },
                "taskTitle": {
                  "type": "string",
                  "nullable": true
                },
                "activityType": {
                  "type": "string",
                  "nullable": true
                },
                "statusFrom": {
                  "type": "string",
                  "nullable": true
                },
                "statusTo": {
                  "type": "string",
                  "nullable": true
                },
                "rag": {
                  "type": "string",
                  "enum": [
                    "on_track",
                    "at_risk",
                    "off_track",
                    null
                  ],
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "decision": {
                  "type": "string",
                  "enum": [
                    "approved",
                    "changes_requested",
                    null
                  ],
                  "nullable": true
                },
                "subjectTitle": {
                  "type": "string",
                  "nullable": true
                },
                "description": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "at",
                "kind",
                "actorName",
                "taskId",
                "taskKey",
                "taskTitle",
                "activityType",
                "statusFrom",
                "statusTo",
                "rag",
                "note",
                "decision",
                "subjectTitle",
                "description"
              ]
            }
          },
          "sourceQuote": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "displayKey": {
                "type": "string"
              },
              "title": {
                "type": "string"
              },
              "totalNetCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "id",
              "displayKey",
              "title",
              "totalNetCents"
            ],
            "nullable": true
          },
          "statusUpdate": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "rag": {
                "type": "string",
                "enum": [
                  "on_track",
                  "at_risk",
                  "off_track"
                ]
              },
              "note": {
                "type": "string"
              },
              "authorName": {
                "type": "string",
                "nullable": true
              },
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
              }
            },
            "required": [
              "id",
              "rag",
              "note",
              "authorName",
              "createdAt"
            ],
            "nullable": true
          }
        },
        "required": [
          "attention",
          "milestones",
          "completion",
          "budget",
          "margin",
          "unbilled",
          "team",
          "recentActivity",
          "feed",
          "sourceQuote",
          "statusUpdate"
        ]
      },
      "TaskBoardResponseDto": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "project",
              "tenant_default"
            ]
          },
          "statuses": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "nullable": true
                },
                "category": {
                  "type": "string",
                  "enum": [
                    "todo",
                    "in_progress",
                    "done",
                    "cancelled"
                  ]
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "wipLimit": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "taskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "projectId",
                "name",
                "color",
                "category",
                "sortOrder",
                "wipLimit",
                "taskCount"
              ]
            }
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "statusId": {
                  "type": "string"
                },
                "tasks": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "projectId": {
                        "type": "string"
                      },
                      "number": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "phaseId": {
                        "type": "string",
                        "nullable": true
                      },
                      "phaseName": {
                        "type": "string",
                        "nullable": true
                      },
                      "phaseSortOrder": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "dimensionValueId": {
                        "type": "string",
                        "nullable": true
                      },
                      "title": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string",
                        "nullable": true
                      },
                      "statusId": {
                        "type": "string"
                      },
                      "statusCategory": {
                        "type": "string",
                        "enum": [
                          "todo",
                          "in_progress",
                          "done",
                          "cancelled"
                        ]
                      },
                      "assigneeMembershipId": {
                        "type": "string",
                        "nullable": true
                      },
                      "assigneeName": {
                        "type": "string",
                        "nullable": true
                      },
                      "priority": {
                        "type": "string",
                        "enum": [
                          "low",
                          "normal",
                          "high",
                          "urgent"
                        ]
                      },
                      "startDate": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "nullable": true
                      },
                      "dueDate": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                        "nullable": true
                      },
                      "estimateMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "progressPct": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 100,
                        "nullable": true
                      },
                      "sortKey": {
                        "type": "string"
                      },
                      "milestoneId": {
                        "type": "string",
                        "nullable": true
                      },
                      "tags": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "color": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "id",
                            "name",
                            "color"
                          ]
                        }
                      },
                      "recurrenceId": {
                        "type": "string",
                        "nullable": true
                      },
                      "fieldValues": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fieldId": {
                              "type": "string"
                            },
                            "value": {}
                          },
                          "required": [
                            "fieldId",
                            "value"
                          ]
                        }
                      },
                      "archivedAt": {
                        "type": "string",
                        "nullable": true
                      },
                      "checklistDoneCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "checklistTotalCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "commentCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "actualMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "nullable": true
                      },
                      "updatedAt": {
                        "type": "string"
                      },
                      "createdAt": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "projectId",
                      "number",
                      "phaseId",
                      "phaseName",
                      "phaseSortOrder",
                      "dimensionValueId",
                      "title",
                      "statusId",
                      "statusCategory",
                      "assigneeMembershipId",
                      "assigneeName",
                      "priority",
                      "startDate",
                      "dueDate",
                      "estimateMinutes",
                      "progressPct",
                      "sortKey",
                      "milestoneId",
                      "tags",
                      "recurrenceId",
                      "fieldValues",
                      "archivedAt",
                      "checklistDoneCount",
                      "checklistTotalCount",
                      "commentCount",
                      "actualMinutes",
                      "updatedAt",
                      "createdAt"
                    ]
                  }
                },
                "totalCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "hasMore": {
                  "type": "boolean"
                }
              },
              "required": [
                "statusId",
                "tasks",
                "totalCount",
                "hasMore"
              ]
            }
          },
          "dependencies": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "predecessorTaskId": {
                  "type": "string"
                },
                "successorTaskId": {
                  "type": "string"
                },
                "lagDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "predecessorTaskId",
                "successorTaskId",
                "lagDays"
              ]
            }
          },
          "milestones": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "taskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "openTaskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "overdueTaskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "projectId",
                "name",
                "date",
                "taskCount",
                "openTaskCount",
                "overdueTaskCount"
              ]
            }
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "number",
                    "date",
                    "select",
                    "multi_select",
                    "checkbox",
                    "url"
                  ]
                },
                "options": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "label": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 60
                      },
                      "color": {
                        "type": "string",
                        "pattern": "^#[0-9a-fA-F]{6}$",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "label"
                    ]
                  }
                },
                "showOnCard": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "archived": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "name",
                "type",
                "options",
                "showOnCard",
                "sortOrder",
                "archived"
              ]
            }
          },
          "taskTimeTracking": {
            "type": "string",
            "enum": [
              "off",
              "optional",
              "required"
            ]
          },
          "criticalPath": {
            "type": "object",
            "properties": {
              "taskIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "totalDays": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "taskIds",
              "totalDays"
            ]
          }
        },
        "required": [
          "source",
          "statuses",
          "columns",
          "dependencies",
          "milestones",
          "fields",
          "taskTimeTracking",
          "criticalPath"
        ]
      },
      "TaskPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "number": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "phaseId": {
                  "type": "string",
                  "nullable": true
                },
                "phaseName": {
                  "type": "string",
                  "nullable": true
                },
                "phaseSortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "statusId": {
                  "type": "string"
                },
                "statusCategory": {
                  "type": "string",
                  "enum": [
                    "todo",
                    "in_progress",
                    "done",
                    "cancelled"
                  ]
                },
                "assigneeMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "assigneeName": {
                  "type": "string",
                  "nullable": true
                },
                "priority": {
                  "type": "string",
                  "enum": [
                    "low",
                    "normal",
                    "high",
                    "urgent"
                  ]
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "estimateMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "progressPct": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 100,
                  "nullable": true
                },
                "sortKey": {
                  "type": "string"
                },
                "milestoneId": {
                  "type": "string",
                  "nullable": true
                },
                "tags": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "color": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "name",
                      "color"
                    ]
                  }
                },
                "recurrenceId": {
                  "type": "string",
                  "nullable": true
                },
                "fieldValues": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldId": {
                        "type": "string"
                      },
                      "value": {}
                    },
                    "required": [
                      "fieldId",
                      "value"
                    ]
                  }
                },
                "archivedAt": {
                  "type": "string",
                  "nullable": true
                },
                "checklistDoneCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "checklistTotalCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "commentCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "actualMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "projectId",
                "number",
                "phaseId",
                "phaseName",
                "phaseSortOrder",
                "dimensionValueId",
                "title",
                "statusId",
                "statusCategory",
                "assigneeMembershipId",
                "assigneeName",
                "priority",
                "startDate",
                "dueDate",
                "estimateMinutes",
                "progressPct",
                "sortKey",
                "milestoneId",
                "tags",
                "recurrenceId",
                "fieldValues",
                "archivedAt",
                "checklistDoneCount",
                "checklistTotalCount",
                "commentCount",
                "actualMinutes",
                "updatedAt",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "TaskOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "CreateTaskDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 8000,
            "nullable": true
          },
          "templateId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "statusId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "phaseId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "assigneeMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "priority": {
            "default": "normal",
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ]
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "dueDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "estimateMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "milestoneId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "tagIds": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "trackTime": {
            "type": "boolean"
          },
          "fixedPriceCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          }
        },
        "required": [
          "title"
        ]
      },
      "TaskViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "number": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "phaseId": {
            "type": "string",
            "nullable": true
          },
          "phaseName": {
            "type": "string",
            "nullable": true
          },
          "phaseSortOrder": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "dimensionValueId": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "statusId": {
            "type": "string"
          },
          "statusCategory": {
            "type": "string",
            "enum": [
              "todo",
              "in_progress",
              "done",
              "cancelled"
            ]
          },
          "assigneeMembershipId": {
            "type": "string",
            "nullable": true
          },
          "assigneeName": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ]
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "dueDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "estimateMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "progressPct": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "sortKey": {
            "type": "string"
          },
          "milestoneId": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "name",
                "color"
              ]
            }
          },
          "recurrenceId": {
            "type": "string",
            "nullable": true
          },
          "fieldValues": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fieldId": {
                  "type": "string"
                },
                "value": {}
              },
              "required": [
                "fieldId",
                "value"
              ]
            }
          },
          "archivedAt": {
            "type": "string",
            "nullable": true
          },
          "checklistDoneCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "checklistTotalCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "commentCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "actualMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "updatedAt": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "projectId",
          "number",
          "phaseId",
          "phaseName",
          "phaseSortOrder",
          "dimensionValueId",
          "title",
          "statusId",
          "statusCategory",
          "assigneeMembershipId",
          "assigneeName",
          "priority",
          "startDate",
          "dueDate",
          "estimateMinutes",
          "progressPct",
          "sortKey",
          "milestoneId",
          "tags",
          "recurrenceId",
          "fieldValues",
          "archivedAt",
          "checklistDoneCount",
          "checklistTotalCount",
          "commentCount",
          "actualMinutes",
          "updatedAt",
          "createdAt"
        ]
      },
      "TaskStatusListResponseDto": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "project",
              "tenant_default"
            ]
          },
          "statuses": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "nullable": true
                },
                "category": {
                  "type": "string",
                  "enum": [
                    "todo",
                    "in_progress",
                    "done",
                    "cancelled"
                  ]
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "wipLimit": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "taskCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "projectId",
                "name",
                "color",
                "category",
                "sortOrder",
                "wipLimit",
                "taskCount"
              ]
            }
          }
        },
        "required": [
          "source",
          "statuses"
        ]
      },
      "TaskDetailResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "number": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "phaseId": {
            "type": "string",
            "nullable": true
          },
          "phaseName": {
            "type": "string",
            "nullable": true
          },
          "phaseSortOrder": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "dimensionValueId": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "statusId": {
            "type": "string"
          },
          "statusCategory": {
            "type": "string",
            "enum": [
              "todo",
              "in_progress",
              "done",
              "cancelled"
            ]
          },
          "assigneeMembershipId": {
            "type": "string",
            "nullable": true
          },
          "assigneeName": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "string",
            "enum": [
              "low",
              "normal",
              "high",
              "urgent"
            ]
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "dueDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "estimateMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "progressPct": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "sortKey": {
            "type": "string"
          },
          "milestoneId": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "name",
                "color"
              ]
            }
          },
          "recurrenceId": {
            "type": "string",
            "nullable": true
          },
          "fieldValues": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fieldId": {
                  "type": "string"
                },
                "value": {}
              },
              "required": [
                "fieldId",
                "value"
              ]
            }
          },
          "archivedAt": {
            "type": "string",
            "nullable": true
          },
          "checklistDoneCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "checklistTotalCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "commentCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "actualMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "updatedAt": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "projectName": {
            "type": "string"
          },
          "projectCode": {
            "type": "string"
          },
          "checklist": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "done": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "assigneeMembershipId": {
                  "type": "string",
                  "nullable": true
                },
                "assigneeName": {
                  "type": "string",
                  "nullable": true
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "title",
                "done",
                "sortOrder",
                "assigneeMembershipId",
                "assigneeName",
                "dueDate"
              ]
            }
          },
          "predecessors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "statusCategory": {
                  "type": "string",
                  "enum": [
                    "todo",
                    "in_progress",
                    "done",
                    "cancelled"
                  ]
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "taskKey": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "external": {
                  "type": "boolean"
                },
                "lagDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "title",
                "statusCategory",
                "dueDate",
                "taskKey",
                "projectId",
                "external",
                "lagDays"
              ]
            }
          },
          "successors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "statusCategory": {
                  "type": "string",
                  "enum": [
                    "todo",
                    "in_progress",
                    "done",
                    "cancelled"
                  ]
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "taskKey": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "external": {
                  "type": "boolean"
                },
                "lagDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "title",
                "statusCategory",
                "dueDate",
                "taskKey",
                "projectId",
                "external",
                "lagDays"
              ]
            }
          },
          "recurrence": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "freq": {
                "type": "string",
                "enum": [
                  "daily",
                  "weekly",
                  "monthly"
                ]
              },
              "interval": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "byWeekday": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "byMonthDay": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991,
                "nullable": true
              },
              "mode": {
                "type": "string",
                "enum": [
                  "schedule",
                  "on_complete"
                ]
              },
              "active": {
                "type": "boolean"
              }
            },
            "required": [
              "id",
              "freq",
              "interval",
              "byWeekday",
              "byMonthDay",
              "mode",
              "active"
            ],
            "nullable": true
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "number",
                    "date",
                    "select",
                    "multi_select",
                    "checkbox",
                    "url"
                  ]
                },
                "options": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "label": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 60
                      },
                      "color": {
                        "type": "string",
                        "pattern": "^#[0-9a-fA-F]{6}$",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "label"
                    ]
                  }
                },
                "showOnCard": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "archived": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "name",
                "type",
                "options",
                "showOnCard",
                "sortOrder",
                "archived"
              ]
            }
          },
          "watching": {
            "type": "boolean"
          },
          "watchers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "name": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "membershipId",
                "name"
              ]
            }
          },
          "taskTimeTracking": {
            "type": "string",
            "enum": [
              "off",
              "optional",
              "required"
            ]
          },
          "permissions": {
            "type": "object",
            "properties": {
              "canEditPlan": {
                "type": "boolean"
              },
              "canMove": {
                "type": "boolean"
              },
              "canComment": {
                "type": "boolean"
              },
              "canEditChecklist": {
                "type": "boolean"
              },
              "canDelete": {
                "type": "boolean"
              }
            },
            "required": [
              "canEditPlan",
              "canMove",
              "canComment",
              "canEditChecklist",
              "canDelete"
            ]
          }
        },
        "required": [
          "id",
          "projectId",
          "number",
          "phaseId",
          "phaseName",
          "phaseSortOrder",
          "dimensionValueId",
          "title",
          "description",
          "statusId",
          "statusCategory",
          "assigneeMembershipId",
          "assigneeName",
          "priority",
          "startDate",
          "dueDate",
          "estimateMinutes",
          "progressPct",
          "sortKey",
          "milestoneId",
          "tags",
          "recurrenceId",
          "fieldValues",
          "archivedAt",
          "checklistDoneCount",
          "checklistTotalCount",
          "commentCount",
          "actualMinutes",
          "updatedAt",
          "createdAt",
          "projectName",
          "projectCode",
          "checklist",
          "predecessors",
          "successors",
          "recurrence",
          "fields",
          "watching",
          "watchers",
          "taskTimeTracking",
          "permissions"
        ]
      },
      "MeTasksResponseDto": {
        "type": "object",
        "properties": {
          "tasks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string"
                },
                "projectName": {
                  "type": "string"
                },
                "projectCode": {
                  "type": "string"
                },
                "number": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "phaseName": {
                  "type": "string",
                  "nullable": true
                },
                "title": {
                  "type": "string"
                },
                "tags": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "color": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "id",
                      "name",
                      "color"
                    ]
                  }
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "statusId": {
                  "type": "string"
                },
                "statusName": {
                  "type": "string"
                },
                "statusCategory": {
                  "type": "string",
                  "enum": [
                    "todo",
                    "in_progress",
                    "done",
                    "cancelled"
                  ]
                },
                "priority": {
                  "type": "string",
                  "enum": [
                    "low",
                    "normal",
                    "high",
                    "urgent"
                  ]
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "checklistDoneCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "checklistTotalCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "commentCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "relation": {
                  "type": "string",
                  "enum": [
                    "assignee",
                    "commenter",
                    "watcher",
                    "project_member"
                  ]
                },
                "estimateMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "myMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "blockedBy": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "taskId": {
                        "type": "string"
                      },
                      "taskKey": {
                        "type": "string"
                      },
                      "title": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "taskId",
                      "taskKey",
                      "title"
                    ]
                  }
                },
                "blocksCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "taskTimeTracking": {
                  "type": "string",
                  "enum": [
                    "off",
                    "optional",
                    "required"
                  ]
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "projectId",
                "projectName",
                "projectCode",
                "number",
                "phaseName",
                "title",
                "tags",
                "description",
                "statusId",
                "statusName",
                "statusCategory",
                "priority",
                "startDate",
                "dueDate",
                "checklistDoneCount",
                "checklistTotalCount",
                "commentCount",
                "relation",
                "estimateMinutes",
                "myMinutes",
                "blockedBy",
                "blocksCount",
                "dimensionValueId",
                "taskTimeTracking",
                "updatedAt"
              ]
            }
          },
          "boards": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "projectId": {
                  "type": "string"
                },
                "statuses": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "category": {
                        "type": "string",
                        "enum": [
                          "todo",
                          "in_progress",
                          "done",
                          "cancelled"
                        ]
                      },
                      "sortOrder": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "id",
                      "name",
                      "category",
                      "sortOrder"
                    ]
                  }
                }
              },
              "required": [
                "projectId",
                "statuses"
              ]
            }
          },
          "checklistItems": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "taskId": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "done": {
                  "type": "boolean"
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "taskTitle": {
                  "type": "string"
                },
                "taskNumber": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "projectId": {
                  "type": "string"
                },
                "projectCode": {
                  "type": "string"
                },
                "projectName": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "taskId",
                "title",
                "done",
                "dueDate",
                "taskTitle",
                "taskNumber",
                "projectId",
                "projectCode",
                "projectName"
              ]
            }
          },
          "waiting": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "notificationId": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "task_mentioned",
                    "task_commented"
                  ]
                },
                "taskId": {
                  "type": "string"
                },
                "taskKey": {
                  "type": "string",
                  "nullable": true
                },
                "taskTitle": {
                  "type": "string",
                  "nullable": true
                },
                "actorName": {
                  "type": "string",
                  "nullable": true
                },
                "preview": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "notificationId",
                "type",
                "taskId",
                "taskKey",
                "taskTitle",
                "actorName",
                "preview",
                "createdAt"
              ]
            }
          },
          "myWeekMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "tasks",
          "boards",
          "checklistItems",
          "waiting",
          "myWeekMinutes"
        ]
      },
      "MeTaskStatusChangeDto": {
        "type": "object",
        "properties": {
          "statusId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "required": [
          "statusId"
        ]
      },
      "BillingIdResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "BillingCandidatesResponseDto": {
        "type": "object",
        "properties": {
          "periodStart": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "periodEnd": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "granularity": {
            "type": "string",
            "enum": [
              "project",
              "phase",
              "task",
              "person",
              "day"
            ]
          },
          "invoiceCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "netCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "vatCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "grossCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "unpricedMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "invoices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "customerId": {
                  "type": "string"
                },
                "customerCode": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                },
                "reference": {
                  "type": "string"
                },
                "netCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "grossCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "lines": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "lineKey": {
                        "type": "string"
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "work",
                          "expense",
                          "trip",
                          "purchase",
                          "manual",
                          "contract",
                          "change_order"
                        ]
                      },
                      "bucketKey": {
                        "type": "string"
                      },
                      "productCode": {
                        "type": "string",
                        "nullable": true
                      },
                      "description": {
                        "type": "string"
                      },
                      "quantity": {
                        "type": "number"
                      },
                      "unit": {
                        "type": "string",
                        "enum": [
                          "hour",
                          "piece",
                          "day",
                          "km",
                          "fixed"
                        ]
                      },
                      "unitPriceCents": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "amountCents": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "vatRate": {
                        "type": "number"
                      },
                      "vatCode": {
                        "type": "string",
                        "nullable": true
                      },
                      "vatCents": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "costCenter": {
                        "type": "string"
                      },
                      "project": {
                        "type": "string"
                      },
                      "projectId": {
                        "type": "string",
                        "nullable": true
                      },
                      "projectPhase": {
                        "type": "string"
                      },
                      "unpriced": {
                        "type": "boolean"
                      },
                      "workedMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "billingBaseMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      },
                      "roundedMinutes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "default": null,
                        "nullable": true
                      }
                    },
                    "required": [
                      "lineKey",
                      "source",
                      "bucketKey",
                      "productCode",
                      "description",
                      "quantity",
                      "unit",
                      "unitPriceCents",
                      "amountCents",
                      "vatRate",
                      "vatCode",
                      "vatCents",
                      "costCenter",
                      "project",
                      "projectId",
                      "projectPhase",
                      "unpriced"
                    ]
                  }
                }
              },
              "required": [
                "customerId",
                "customerCode",
                "customerName",
                "reference",
                "netCents",
                "vatCents",
                "grossCents",
                "lines"
              ]
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "detail": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "code",
                "detail"
              ]
            }
          },
          "candidateHash": {
            "type": "string"
          }
        },
        "required": [
          "periodStart",
          "periodEnd",
          "granularity",
          "invoiceCount",
          "netCents",
          "vatCents",
          "grossCents",
          "unpricedMinutes",
          "invoices",
          "warnings",
          "candidateHash"
        ]
      },
      "BillingBatchListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "invoice",
                    "write_off",
                    "invoice_document"
                  ]
                },
                "writeOffReason": {
                  "type": "string",
                  "nullable": true
                },
                "periodFrom": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "periodTo": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "targetId": {
                  "type": "string",
                  "nullable": true
                },
                "adapterKey": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "exported",
                    "canceled",
                    "document"
                  ]
                },
                "customerCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "lineCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "netCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "grossCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "createdAt": {
                  "type": "string"
                },
                "canceledAt": {
                  "type": "string",
                  "nullable": true
                },
                "cancelReason": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "kind",
                "writeOffReason",
                "periodFrom",
                "periodTo",
                "targetId",
                "adapterKey",
                "status",
                "customerCount",
                "lineCount",
                "netCents",
                "vatCents",
                "grossCents",
                "createdAt",
                "canceledAt",
                "cancelReason"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateBillingBatchDto": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "to": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "targetId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "kind": {
            "type": "string",
            "enum": [
              "invoice",
              "write_off",
              "invoice_document"
            ]
          },
          "writeOffReason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "granularity": {
            "type": "string",
            "enum": [
              "project",
              "phase",
              "task",
              "person",
              "day"
            ]
          },
          "exclude": {
            "maxItems": 2000,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500
            }
          },
          "adjustments": {
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "lineKey": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 500
                },
                "billedMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 600000
                },
                "reason": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 500
                }
              },
              "required": [
                "lineKey",
                "billedMinutes",
                "reason"
              ]
            }
          },
          "candidateHash": {
            "type": "string",
            "maxLength": 128
          },
          "manualLines": {
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "customerId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "productCode": {
                  "type": "string",
                  "maxLength": 64,
                  "default": null,
                  "nullable": true
                },
                "description": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "quantity": {
                  "default": 1,
                  "type": "number",
                  "exclusiveMinimum": true,
                  "minimum": 0
                },
                "unit": {
                  "default": "fixed",
                  "type": "string",
                  "enum": [
                    "hour",
                    "piece",
                    "day",
                    "km",
                    "fixed"
                  ]
                },
                "unitPriceCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatRate": {
                  "default": 0,
                  "type": "number",
                  "minimum": 0,
                  "maximum": 100
                },
                "vatCode": {
                  "type": "string",
                  "maxLength": 32,
                  "default": null,
                  "nullable": true
                },
                "costCenter": {
                  "default": "",
                  "type": "string",
                  "maxLength": 64
                },
                "project": {
                  "default": "",
                  "type": "string",
                  "maxLength": 120
                }
              },
              "required": [
                "customerId",
                "description",
                "unitPriceCents"
              ]
            }
          }
        },
        "required": [
          "from",
          "to",
          "targetId"
        ]
      },
      "BillingDeliveryListResponseDto": {
        "type": "object",
        "properties": {
          "deliveries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "batchId": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "delivering",
                    "delivered",
                    "failed"
                  ]
                },
                "attempts": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "errorCode": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "batchId",
                "status",
                "attempts",
                "errorCode",
                "createdAt",
                "updatedAt"
              ]
            }
          }
        },
        "required": [
          "deliveries"
        ]
      },
      "InvoicePageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "documentType": {
                  "type": "string",
                  "enum": [
                    "invoice",
                    "credit_note",
                    "reminder",
                    "advance"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "issued"
                  ]
                },
                "lane": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "approved",
                    "issued",
                    "sent",
                    "overdue",
                    "paid",
                    "credited"
                  ]
                },
                "reviewStatus": {
                  "type": "string",
                  "enum": [
                    "none",
                    "requested",
                    "approved"
                  ]
                },
                "invoiceNumber": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "invoiceNumberText": {
                  "type": "string",
                  "nullable": true
                },
                "customerId": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                },
                "invoiceDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "periodFrom": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "periodTo": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "language": {
                  "type": "string",
                  "enum": [
                    "fi",
                    "sv",
                    "en"
                  ]
                },
                "netTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "vatTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "grossTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "openCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "overdueDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "dispatchStatus": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "sending",
                    "sent",
                    "delivered",
                    "failed",
                    null
                  ],
                  "nullable": true
                },
                "dispatchChannel": {
                  "type": "string",
                  "enum": [
                    "einvoice",
                    "email",
                    "manual",
                    "print",
                    null
                  ],
                  "nullable": true
                },
                "sentAt": {
                  "type": "string",
                  "nullable": true
                },
                "creditedByInvoiceId": {
                  "type": "string",
                  "nullable": true
                },
                "lineCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "documentType",
                "status",
                "lane",
                "reviewStatus",
                "invoiceNumber",
                "invoiceNumberText",
                "customerId",
                "customerName",
                "invoiceDate",
                "dueDate",
                "periodFrom",
                "periodTo",
                "language",
                "netTotalCents",
                "vatTotalCents",
                "grossTotalCents",
                "openCents",
                "overdueDays",
                "dispatchStatus",
                "dispatchChannel",
                "sentAt",
                "creditedByInvoiceId",
                "lineCount",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "InvoicingSummaryResponseDto": {
        "type": "object",
        "properties": {
          "asOf": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "invoicedThisMonthCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "openArCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "overdueCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "overdueInvoiceCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "billableNowCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "wipCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "draftCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "draftValueCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          }
        },
        "required": [
          "asOf",
          "invoicedThisMonthCents",
          "openArCents",
          "overdueCents",
          "overdueInvoiceCount",
          "billableNowCents",
          "wipCents",
          "draftCount",
          "draftValueCents"
        ]
      },
      "CreateInvoiceDraftsDto": {
        "type": "object",
        "properties": {
          "periodFrom": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "periodTo": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "customerIds": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "projectIds": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "grouping": {
            "type": "string",
            "enum": [
              "combine",
              "separate"
            ]
          },
          "granularity": {
            "type": "string",
            "enum": [
              "project",
              "phase",
              "task",
              "person",
              "day"
            ]
          },
          "profileId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "invoiceDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          }
        },
        "required": [
          "periodFrom",
          "periodTo"
        ],
        "additionalProperties": false
      },
      "CreateInvoiceDraftsResponseDto": {
        "type": "object",
        "properties": {
          "drafts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "invoiceId": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "lineCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "netTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "vatTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "grossTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                }
              },
              "required": [
                "invoiceId",
                "customerId",
                "customerName",
                "projectId",
                "lineCount",
                "netTotalCents",
                "vatTotalCents",
                "grossTotalCents"
              ]
            }
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "customerId": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                }
              },
              "required": [
                "customerId",
                "code"
              ]
            }
          }
        },
        "required": [
          "drafts",
          "skipped"
        ]
      },
      "InvoiceViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "batchId": {
            "type": "string"
          },
          "documentType": {
            "type": "string",
            "enum": [
              "invoice",
              "credit_note",
              "reminder",
              "advance"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "issued"
            ]
          },
          "lane": {
            "type": "string",
            "enum": [
              "draft",
              "approved",
              "issued",
              "sent",
              "overdue",
              "paid",
              "credited"
            ]
          },
          "reviewStatus": {
            "type": "string",
            "enum": [
              "none",
              "requested",
              "approved"
            ]
          },
          "customerId": {
            "type": "string"
          },
          "customerName": {
            "type": "string"
          },
          "customerCode": {
            "type": "string"
          },
          "contactId": {
            "type": "string",
            "nullable": true
          },
          "contactName": {
            "type": "string",
            "nullable": true
          },
          "contactEmail": {
            "type": "string",
            "nullable": true
          },
          "profileId": {
            "type": "string"
          },
          "originalInvoiceId": {
            "type": "string",
            "nullable": true
          },
          "originalInvoiceNumberText": {
            "type": "string",
            "nullable": true
          },
          "invoiceNumber": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "invoiceNumberText": {
            "type": "string",
            "nullable": true
          },
          "invoiceDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "dueDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "periodFrom": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "periodTo": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "language": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "currency": {
            "type": "string",
            "enum": [
              "EUR"
            ]
          },
          "vatTreatment": {
            "type": "string",
            "enum": [
              "standard",
              "reverse_charge_construction",
              "tax_exempt"
            ]
          },
          "paymentTermDays": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "penaltyInterestPercent": {
            "type": "number"
          },
          "referenceNumber": {
            "type": "string",
            "nullable": true
          },
          "referenceType": {
            "type": "string",
            "enum": [
              "domestic",
              "rf"
            ]
          },
          "virtualBarcode": {
            "type": "string",
            "nullable": true
          },
          "buyerReference": {
            "type": "string",
            "nullable": true
          },
          "orderNumber": {
            "type": "string",
            "nullable": true
          },
          "contractNumber": {
            "type": "string",
            "nullable": true
          },
          "ourReference": {
            "type": "string",
            "nullable": true
          },
          "noteBeforeLines": {
            "type": "string",
            "nullable": true
          },
          "noteAfterLines": {
            "type": "string",
            "nullable": true
          },
          "sellerSnapshot": {
            "type": "object",
            "properties": {
              "legalName": {
                "type": "string"
              },
              "businessId": {
                "type": "string"
              },
              "vatId": {
                "type": "string",
                "nullable": true
              },
              "streetAddress": {
                "type": "string"
              },
              "postalCode": {
                "type": "string"
              },
              "city": {
                "type": "string"
              },
              "country": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "nullable": true
              },
              "phone": {
                "type": "string",
                "nullable": true
              },
              "iban": {
                "type": "string"
              },
              "bic": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "legalName",
              "businessId",
              "vatId",
              "streetAddress",
              "postalCode",
              "city",
              "country",
              "email",
              "phone",
              "iban",
              "bic"
            ],
            "nullable": true
          },
          "customerSnapshot": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "businessId": {
                "type": "string",
                "nullable": true
              },
              "vatId": {
                "type": "string",
                "nullable": true
              },
              "streetAddress": {
                "type": "string",
                "nullable": true
              },
              "postalCode": {
                "type": "string",
                "nullable": true
              },
              "city": {
                "type": "string",
                "nullable": true
              },
              "country": {
                "type": "string",
                "nullable": true
              },
              "invoiceEmail": {
                "type": "string",
                "nullable": true
              },
              "einvoiceAddress": {
                "type": "string",
                "nullable": true
              },
              "einvoiceOperator": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "name",
              "businessId",
              "vatId",
              "streetAddress",
              "postalCode",
              "city",
              "country",
              "invoiceEmail",
              "einvoiceAddress",
              "einvoiceOperator"
            ],
            "nullable": true
          },
          "netTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "vatTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "grossTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "vatGroups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "vatRate": {
                  "type": "number"
                },
                "netCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                }
              },
              "required": [
                "vatRate",
                "netCents",
                "vatCents"
              ]
            }
          },
          "openCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "paidCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "creditAppliedCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "overdueDays": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "issuedAt": {
            "type": "string",
            "nullable": true
          },
          "issuedByName": {
            "type": "string",
            "nullable": true
          },
          "sentAt": {
            "type": "string",
            "nullable": true
          },
          "creditedByInvoiceId": {
            "type": "string",
            "nullable": true
          },
          "creditedByInvoiceNumberText": {
            "type": "string",
            "nullable": true
          },
          "recurringScheduleId": {
            "type": "string",
            "nullable": true
          },
          "paymentTermId": {
            "type": "string",
            "nullable": true
          },
          "termNetDays": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "termDiscountDays": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "termDiscountPercent": {
            "type": "number",
            "nullable": true
          },
          "cashDiscountCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "advanceAppliedCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "customerAdvanceBalanceCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "preDueRemindedAt": {
            "type": "string",
            "nullable": true
          },
          "shareUrl": {
            "type": "string",
            "nullable": true
          },
          "effectiveDispatchRoute": {
            "type": "object",
            "properties": {
              "channel": {
                "type": "string",
                "enum": [
                  "einvoice",
                  "email",
                  "manual",
                  "print"
                ]
              },
              "recipient": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "channel",
              "recipient"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "groupKey": {
                  "type": "string",
                  "nullable": true
                },
                "groupTitle": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "work",
                    "expense",
                    "trip",
                    "purchase",
                    "contract",
                    "change_order",
                    "manual",
                    "discount",
                    "advance"
                  ]
                },
                "bucketKey": {
                  "type": "string",
                  "nullable": true
                },
                "description": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "unit": {
                  "type": "string",
                  "enum": [
                    "hour",
                    "piece",
                    "day",
                    "km",
                    "fixed"
                  ]
                },
                "unitPriceCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "discountPercent": {
                  "type": "number",
                  "nullable": true
                },
                "vatRate": {
                  "type": "number"
                },
                "netAmountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "vatAmountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "disposition": {
                  "type": "string",
                  "enum": [
                    "bill",
                    "later",
                    "write_off"
                  ]
                },
                "writeOffReason": {
                  "type": "string",
                  "nullable": true
                },
                "lineKey": {
                  "type": "string",
                  "nullable": true
                },
                "minutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "workedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "billingBaseMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "roundedMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "taskId": {
                  "type": "string",
                  "nullable": true
                },
                "installmentId": {
                  "type": "string",
                  "nullable": true
                },
                "changeOrderId": {
                  "type": "string",
                  "nullable": true
                },
                "orderReference": {
                  "type": "string",
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "sortOrder",
                "groupKey",
                "groupTitle",
                "source",
                "bucketKey",
                "description",
                "quantity",
                "unit",
                "unitPriceCents",
                "discountPercent",
                "vatRate",
                "netAmountCents",
                "vatAmountCents",
                "disposition",
                "writeOffReason",
                "lineKey",
                "minutes",
                "workedMinutes",
                "billingBaseMinutes",
                "roundedMinutes",
                "projectId",
                "projectName",
                "taskId",
                "installmentId",
                "changeOrderId",
                "updatedAt"
              ]
            }
          },
          "preflight": {
            "type": "object",
            "properties": {
              "canIssue": {
                "type": "boolean"
              },
              "blockers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "code",
                    "detail"
                  ]
                }
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "code",
                    "detail"
                  ]
                }
              }
            },
            "required": [
              "canIssue",
              "blockers",
              "warnings"
            ]
          },
          "dispatches": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "invoiceId": {
                  "type": "string"
                },
                "channel": {
                  "type": "string",
                  "enum": [
                    "einvoice",
                    "email",
                    "manual",
                    "print"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "sending",
                    "sent",
                    "delivered",
                    "failed"
                  ]
                },
                "recipient": {
                  "type": "string"
                },
                "operatorMessageId": {
                  "type": "string",
                  "nullable": true
                },
                "errorCode": {
                  "type": "string",
                  "nullable": true
                },
                "testMode": {
                  "type": "boolean"
                },
                "attemptNumber": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "artifactAttachmentId": {
                  "type": "string",
                  "nullable": true
                },
                "sentAt": {
                  "type": "string",
                  "nullable": true
                },
                "deliveredAt": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "invoiceId",
                "channel",
                "status",
                "recipient",
                "operatorMessageId",
                "errorCode",
                "testMode",
                "attemptNumber",
                "artifactAttachmentId",
                "sentAt",
                "deliveredAt",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          "settlements": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "payment",
                    "credit",
                    "cash_discount"
                  ]
                },
                "sourceId": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "reference": {
                  "type": "string",
                  "nullable": true
                },
                "payerName": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "manual",
                    "netvisor",
                    "camt054",
                    null
                  ],
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "kind",
                "sourceId",
                "date",
                "amountCents",
                "reference",
                "payerName",
                "source",
                "createdAt"
              ]
            }
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "actorName": {
                  "type": "string",
                  "nullable": true
                },
                "detail": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "type",
                "actorName",
                "detail",
                "createdAt"
              ]
            }
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "batchId",
          "documentType",
          "status",
          "lane",
          "reviewStatus",
          "customerId",
          "customerName",
          "customerCode",
          "contactId",
          "contactName",
          "contactEmail",
          "profileId",
          "originalInvoiceId",
          "originalInvoiceNumberText",
          "invoiceNumber",
          "invoiceNumberText",
          "invoiceDate",
          "dueDate",
          "periodFrom",
          "periodTo",
          "language",
          "currency",
          "vatTreatment",
          "paymentTermDays",
          "penaltyInterestPercent",
          "referenceNumber",
          "referenceType",
          "virtualBarcode",
          "buyerReference",
          "orderNumber",
          "contractNumber",
          "ourReference",
          "noteBeforeLines",
          "noteAfterLines",
          "sellerSnapshot",
          "customerSnapshot",
          "netTotalCents",
          "vatTotalCents",
          "grossTotalCents",
          "vatGroups",
          "openCents",
          "paidCents",
          "creditAppliedCents",
          "overdueDays",
          "issuedAt",
          "issuedByName",
          "sentAt",
          "creditedByInvoiceId",
          "creditedByInvoiceNumberText",
          "recurringScheduleId",
          "lines",
          "preflight",
          "dispatches",
          "settlements",
          "events",
          "createdAt",
          "updatedAt"
        ]
      },
      "UpdateInvoiceDraftDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "profileId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "language": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "invoiceDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "dueDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "periodFrom": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "periodTo": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "paymentTermDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 90
          },
          "paymentTermId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "penaltyInterestPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 30,
            "multipleOf": 0.1
          },
          "vatTreatment": {
            "type": "string",
            "enum": [
              "standard",
              "reverse_charge_construction",
              "tax_exempt"
            ]
          },
          "referenceType": {
            "type": "string",
            "enum": [
              "domestic",
              "rf"
            ]
          },
          "buyerReference": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "orderNumber": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "contractNumber": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "ourReference": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "noteBeforeLines": {
            "type": "string",
            "maxLength": 2000,
            "nullable": true
          },
          "noteAfterLines": {
            "type": "string",
            "maxLength": 2000,
            "nullable": true
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "DeleteInvoiceDraftDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500
          }
        },
        "additionalProperties": false
      },
      "InvoiceOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "AddManualLineDto": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "quantity": {
            "default": 1,
            "type": "number",
            "exclusiveMinimum": true,
            "maximum": 9999999,
            "minimum": 0
          },
          "unit": {
            "default": "fixed",
            "type": "string",
            "enum": [
              "hour",
              "piece",
              "day",
              "km",
              "fixed"
            ]
          },
          "unitPriceCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "discountPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "vatRate": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000
          },
          "groupKey": {
            "type": "string",
            "maxLength": 64,
            "nullable": true
          },
          "groupTitle": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "taskId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "orderReference": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "source": {
            "default": "manual",
            "type": "string",
            "enum": [
              "manual",
              "discount"
            ]
          }
        },
        "required": [
          "description",
          "unitPriceCents"
        ],
        "additionalProperties": false
      },
      "UpdateDraftLineDto": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "quantity": {
            "type": "number",
            "exclusiveMinimum": true,
            "maximum": 9999999,
            "minimum": 0
          },
          "unitPriceCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "discountPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "vatRate": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000
          },
          "groupKey": {
            "type": "string",
            "maxLength": 64,
            "nullable": true
          },
          "groupTitle": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "disposition": {
            "type": "string",
            "enum": [
              "bill",
              "later",
              "write_off"
            ]
          },
          "writeOffReason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "nullable": true
          },
          "orderReference": {
            "type": "string",
            "maxLength": 70,
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReorderDraftLinesDto": {
        "type": "object",
        "properties": {
          "lineIds": {
            "minItems": 1,
            "maxItems": 1000,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        },
        "required": [
          "lineIds"
        ],
        "additionalProperties": false
      },
      "SetInvoiceReviewDto": {
        "type": "object",
        "properties": {
          "reviewStatus": {
            "type": "string",
            "enum": [
              "requested",
              "approved"
            ]
          },
          "comment": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "reviewStatus"
        ],
        "additionalProperties": false
      },
      "IssueInvoiceDto": {
        "type": "object",
        "properties": {
          "expectedTotalGrossCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "invoiceDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "expectedUpdatedAt": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "IssueResultDto": {
        "type": "object",
        "properties": {
          "invoiceId": {
            "type": "string"
          },
          "invoiceNumber": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "invoiceNumberText": {
            "type": "string"
          },
          "invoiceDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "dueDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "referenceNumber": {
            "type": "string"
          },
          "netTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "vatTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "grossTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "releasedSourceCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "writeOffLineCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "invoiceId",
          "invoiceNumber",
          "invoiceNumberText",
          "invoiceDate",
          "dueDate",
          "referenceNumber",
          "netTotalCents",
          "vatTotalCents",
          "grossTotalCents",
          "releasedSourceCount",
          "writeOffLineCount"
        ]
      },
      "CreditNoteDto": {
        "type": "object",
        "properties": {
          "lines": {
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "lineId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "quantity": {
                  "type": "number",
                  "exclusiveMinimum": true,
                  "maximum": 9999999,
                  "minimum": 0
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "releaseSources": {
                  "type": "boolean"
                },
                "writeOffReason": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 500
                }
              },
              "required": [
                "lineId"
              ],
              "additionalProperties": false
            }
          },
          "releaseSources": {
            "default": false,
            "type": "boolean"
          },
          "writeOffReason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "reissue": {
            "default": false,
            "type": "boolean"
          },
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          }
        },
        "required": [
          "reason"
        ],
        "additionalProperties": false
      },
      "CreditNoteResultDto": {
        "type": "object",
        "properties": {
          "creditNoteId": {
            "type": "string"
          },
          "originalInvoiceId": {
            "type": "string"
          },
          "netTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "vatTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "grossTotalCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "releasedSourceCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "reissuedDraftInvoiceId": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "creditNoteId",
          "originalInvoiceId",
          "netTotalCents",
          "vatTotalCents",
          "grossTotalCents",
          "releasedSourceCount",
          "reissuedDraftInvoiceId"
        ]
      },
      "InvoiceDispatchListResponseDto": {
        "type": "object",
        "properties": {
          "dispatches": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "invoiceId": {
                  "type": "string"
                },
                "channel": {
                  "type": "string",
                  "enum": [
                    "einvoice",
                    "email",
                    "manual",
                    "print"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "sending",
                    "sent",
                    "delivered",
                    "failed"
                  ]
                },
                "recipient": {
                  "type": "string"
                },
                "operatorMessageId": {
                  "type": "string",
                  "nullable": true
                },
                "errorCode": {
                  "type": "string",
                  "nullable": true
                },
                "testMode": {
                  "type": "boolean"
                },
                "attemptNumber": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "artifactAttachmentId": {
                  "type": "string",
                  "nullable": true
                },
                "sentAt": {
                  "type": "string",
                  "nullable": true
                },
                "deliveredAt": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "invoiceId",
                "channel",
                "status",
                "recipient",
                "operatorMessageId",
                "errorCode",
                "testMode",
                "attemptNumber",
                "artifactAttachmentId",
                "sentAt",
                "deliveredAt",
                "createdAt",
                "updatedAt"
              ]
            }
          }
        },
        "required": [
          "dispatches"
        ]
      },
      "DispatchRequestDto": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "einvoice",
              "email",
              "manual",
              "print"
            ]
          },
          "recipientOverride": {
            "type": "string",
            "maxLength": 320
          },
          "note": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "additionalProperties": false
      },
      "InvoiceDispatchViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "invoiceId": {
            "type": "string"
          },
          "channel": {
            "type": "string",
            "enum": [
              "einvoice",
              "email",
              "manual",
              "print"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "sending",
              "sent",
              "delivered",
              "failed"
            ]
          },
          "recipient": {
            "type": "string"
          },
          "operatorMessageId": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "testMode": {
            "type": "boolean"
          },
          "attemptNumber": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "artifactAttachmentId": {
            "type": "string",
            "nullable": true
          },
          "sentAt": {
            "type": "string",
            "nullable": true
          },
          "deliveredAt": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "invoiceId",
          "channel",
          "status",
          "recipient",
          "operatorMessageId",
          "errorCode",
          "testMode",
          "attemptNumber",
          "artifactAttachmentId",
          "sentAt",
          "deliveredAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "PaymentPageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "paymentDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "reference": {
                  "type": "string",
                  "nullable": true
                },
                "payerName": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "manual",
                    "netvisor",
                    "camt054"
                  ]
                },
                "sourceRef": {
                  "type": "string",
                  "nullable": true
                },
                "bankImportId": {
                  "type": "string",
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "allocatedCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "unallocatedCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "paymentId": {
                        "type": "string"
                      },
                      "invoiceId": {
                        "type": "string"
                      },
                      "invoiceNumberText": {
                        "type": "string",
                        "nullable": true
                      },
                      "customerName": {
                        "type": "string",
                        "nullable": true
                      },
                      "amountCents": {
                        "type": "integer",
                        "minimum": -2147483647,
                        "maximum": 2147483647
                      },
                      "createdAt": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "id",
                      "paymentId",
                      "invoiceId",
                      "invoiceNumberText",
                      "customerName",
                      "amountCents",
                      "createdAt"
                    ]
                  }
                },
                "createdByName": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "paymentDate",
                "amountCents",
                "reference",
                "payerName",
                "source",
                "sourceRef",
                "bankImportId",
                "note",
                "allocatedCents",
                "unallocatedCents",
                "allocations",
                "createdByName",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "RecordPaymentDto": {
        "type": "object",
        "properties": {
          "paymentDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "amountCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "reference": {
            "type": "string",
            "maxLength": 35
          },
          "payerName": {
            "type": "string",
            "maxLength": 200
          },
          "note": {
            "type": "string",
            "maxLength": 500
          },
          "allocations": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "invoiceId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                }
              },
              "required": [
                "invoiceId",
                "amountCents"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "paymentDate",
          "amountCents"
        ],
        "additionalProperties": false
      },
      "PaymentViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "paymentDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "amountCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "reference": {
            "type": "string",
            "nullable": true
          },
          "payerName": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "netvisor",
              "camt054"
            ]
          },
          "sourceRef": {
            "type": "string",
            "nullable": true
          },
          "bankImportId": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "allocatedCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "unallocatedCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "allocations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "paymentId": {
                  "type": "string"
                },
                "invoiceId": {
                  "type": "string"
                },
                "invoiceNumberText": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "paymentId",
                "invoiceId",
                "invoiceNumberText",
                "customerName",
                "amountCents",
                "createdAt"
              ]
            }
          },
          "createdByName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "paymentDate",
          "amountCents",
          "reference",
          "payerName",
          "source",
          "sourceRef",
          "bankImportId",
          "note",
          "allocatedCents",
          "unallocatedCents",
          "allocations",
          "createdByName",
          "createdAt"
        ]
      },
      "ArAgingResponseDto": {
        "type": "object",
        "properties": {
          "asOf": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "customerId": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                },
                "invoiceCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "notDueCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "days0to30Cents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "days31to60Cents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "days61to90Cents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "days90PlusCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "overdueCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "totalOpenCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                }
              },
              "required": [
                "customerId",
                "customerName",
                "invoiceCount",
                "notDueCents",
                "days0to30Cents",
                "days31to60Cents",
                "days61to90Cents",
                "days90PlusCents",
                "overdueCents",
                "totalOpenCents"
              ]
            }
          },
          "totals": {
            "type": "object",
            "properties": {
              "invoiceCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "notDueCents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              },
              "days0to30Cents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              },
              "days31to60Cents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              },
              "days61to90Cents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              },
              "days90PlusCents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              },
              "overdueCents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              },
              "totalOpenCents": {
                "type": "integer",
                "minimum": -2147483647,
                "maximum": 2147483647
              }
            },
            "required": [
              "invoiceCount",
              "notDueCents",
              "days0to30Cents",
              "days31to60Cents",
              "days61to90Cents",
              "days90PlusCents",
              "overdueCents",
              "totalOpenCents"
            ]
          }
        },
        "required": [
          "asOf",
          "rows",
          "totals"
        ]
      },
      "BankImportListResponseDto": {
        "type": "object",
        "properties": {
          "imports": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "importId": {
                  "type": "string"
                },
                "fileName": {
                  "type": "string"
                },
                "importedAt": {
                  "type": "string"
                },
                "rowCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "matchedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "unmatchedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "duplicateCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "totalAmountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "importedByName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "importId",
                "fileName",
                "importedAt",
                "rowCount",
                "matchedCount",
                "unmatchedCount",
                "duplicateCount",
                "totalAmountCents",
                "importedByName"
              ]
            }
          }
        },
        "required": [
          "imports"
        ]
      },
      "ImportBankFileDto": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "contentBase64": {
            "type": "string",
            "minLength": 1,
            "maxLength": 8000000
          }
        },
        "required": [
          "fileName",
          "contentBase64"
        ],
        "additionalProperties": false
      },
      "ImportResultViewDto": {
        "type": "object",
        "properties": {
          "importId": {
            "type": "string"
          },
          "fileName": {
            "type": "string"
          },
          "importedAt": {
            "type": "string"
          },
          "rowCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "matchedCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "unmatchedCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "duplicateCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "totalAmountCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string",
                  "enum": [
                    "matched",
                    "unmatched",
                    "duplicate"
                  ]
                },
                "valueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "reference": {
                  "type": "string",
                  "nullable": true
                },
                "payerName": {
                  "type": "string",
                  "nullable": true
                },
                "sourceRef": {
                  "type": "string",
                  "nullable": true
                },
                "paymentId": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceId": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceNumberText": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "status",
                "valueDate",
                "amountCents",
                "reference",
                "payerName",
                "sourceRef",
                "paymentId",
                "invoiceId",
                "invoiceNumberText"
              ]
            }
          }
        },
        "required": [
          "importId",
          "fileName",
          "importedAt",
          "rowCount",
          "matchedCount",
          "unmatchedCount",
          "duplicateCount",
          "totalAmountCents",
          "rows"
        ]
      },
      "CustomerPaymentBehaviourDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string"
          },
          "averageDaysToPay": {
            "type": "number",
            "nullable": true
          },
          "paidInvoiceCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "overdueOpenCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "overdueOpenCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          }
        },
        "required": [
          "customerId",
          "averageDaysToPay",
          "paidInvoiceCount",
          "overdueOpenCount",
          "overdueOpenCents"
        ]
      },
      "CustomerAdvanceBalanceResponseDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string"
          },
          "availableCents": {
            "type": "integer",
            "minimum": -2147483647,
            "maximum": 2147483647
          },
          "advances": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "advanceInvoiceId": {
                  "type": "string"
                },
                "invoiceNumberText": {
                  "type": "string",
                  "nullable": true
                },
                "invoiceDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "grossTotalCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "paidCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "appliedCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                },
                "availableCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                }
              },
              "required": [
                "advanceInvoiceId",
                "invoiceNumberText",
                "invoiceDate",
                "grossTotalCents",
                "paidCents",
                "appliedCents",
                "availableCents"
              ]
            }
          }
        },
        "required": [
          "customerId",
          "availableCents",
          "advances"
        ]
      },
      "AllocatePaymentDto": {
        "type": "object",
        "properties": {
          "allocations": {
            "minItems": 1,
            "maxItems": 100,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "invoiceId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -2147483647,
                  "maximum": 2147483647
                }
              },
              "required": [
                "invoiceId",
                "amountCents"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "allocations"
        ],
        "additionalProperties": false
      },
      "RecurringScheduleListResponseDto": {
        "type": "object",
        "properties": {
          "schedules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                },
                "contactId": {
                  "type": "string",
                  "nullable": true
                },
                "contactName": {
                  "type": "string",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "projectName": {
                  "type": "string",
                  "nullable": true
                },
                "profileId": {
                  "type": "string"
                },
                "cadence": {
                  "type": "string",
                  "enum": [
                    "monthly",
                    "quarterly",
                    "weekly"
                  ]
                },
                "dayOfPeriod": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "weekday": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "nextRunDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "includeTimeMaterials": {
                  "type": "boolean"
                },
                "templateLines": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "description": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      },
                      "quantity": {
                        "default": 1,
                        "type": "number",
                        "exclusiveMinimum": true,
                        "maximum": 9999999,
                        "minimum": 0
                      },
                      "unit": {
                        "default": "fixed",
                        "type": "string",
                        "enum": [
                          "hour",
                          "piece",
                          "day",
                          "km",
                          "fixed"
                        ]
                      },
                      "unitPriceCents": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      },
                      "vatRate": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      "sortOrder": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 100000
                      }
                    },
                    "required": [
                      "description",
                      "unitPriceCents"
                    ],
                    "additionalProperties": false
                  }
                },
                "paymentTermDays": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "language": {
                  "type": "string",
                  "enum": [
                    "fi",
                    "sv",
                    "en",
                    null
                  ],
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "lastRunPeriod": {
                  "type": "string",
                  "nullable": true
                },
                "lastGeneratedInvoiceId": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "customerName",
                "contactId",
                "contactName",
                "projectId",
                "projectName",
                "profileId",
                "cadence",
                "dayOfPeriod",
                "nextRunDate",
                "endDate",
                "includeTimeMaterials",
                "templateLines",
                "paymentTermDays",
                "language",
                "active",
                "lastRunPeriod",
                "lastGeneratedInvoiceId",
                "createdAt",
                "updatedAt"
              ]
            }
          }
        },
        "required": [
          "schedules"
        ]
      },
      "RecurringRunListResponseDto": {
        "type": "object",
        "properties": {
          "runs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "scheduleId": {
                  "type": "string",
                  "nullable": true
                },
                "runAt": {
                  "type": "string"
                },
                "trigger": {
                  "type": "string",
                  "enum": [
                    "tick",
                    "manual"
                  ]
                },
                "createdCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "skippedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "failedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "triggeredByName": {
                  "type": "string",
                  "nullable": true
                },
                "details": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "scheduleId": {
                        "type": "string"
                      },
                      "customerName": {
                        "type": "string",
                        "nullable": true
                      },
                      "outcome": {
                        "type": "string",
                        "enum": [
                          "created",
                          "skipped",
                          "failed"
                        ]
                      },
                      "invoiceId": {
                        "type": "string",
                        "nullable": true
                      },
                      "code": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "scheduleId",
                      "customerName",
                      "outcome",
                      "invoiceId",
                      "code"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "scheduleId",
                "runAt",
                "trigger",
                "createdCount",
                "skippedCount",
                "failedCount",
                "triggeredByName",
                "details"
              ]
            }
          }
        },
        "required": [
          "runs"
        ]
      },
      "QuotePageResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "number": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "displayKey": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "sent",
                    "accepted",
                    "declined",
                    "expired"
                  ]
                },
                "validUntil": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                },
                "totalNetCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "totalGrossCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "dealId": {
                  "type": "string",
                  "nullable": true
                },
                "templateName": {
                  "type": "string",
                  "nullable": true
                },
                "updatedAt": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "number",
                "displayKey",
                "customerName",
                "title",
                "status",
                "validUntil",
                "totalNetCents",
                "totalGrossCents",
                "projectId",
                "dealId",
                "templateName",
                "updatedAt",
                "createdAt"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          },
          "meta": {
            "type": "object",
            "properties": {
              "byStatus": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "draft",
                        "sent",
                        "accepted",
                        "declined",
                        "expired"
                      ]
                    },
                    "count": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "netCents": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": [
                    "status",
                    "count",
                    "netCents"
                  ]
                }
              }
            },
            "required": [
              "byStatus"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateQuoteDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "language": {
            "default": "fi",
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "validUntil": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "dealId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          }
        },
        "required": [
          "customerId",
          "title"
        ]
      },
      "QuoteIdResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "QuoteStatsResponseDto": {
        "type": "object",
        "properties": {
          "months": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "month": {
                  "type": "string"
                },
                "sentCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "sentNetCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "acceptedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "acceptedNetCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "declinedCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "hitratePct": {
                  "type": "number",
                  "nullable": true
                }
              },
              "required": [
                "month",
                "sentCount",
                "sentNetCents",
                "acceptedCount",
                "acceptedNetCents",
                "declinedCount",
                "hitratePct"
              ]
            }
          },
          "totals": {
            "type": "object",
            "properties": {
              "sentCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "sentNetCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "acceptedCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "acceptedNetCents": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "declinedCount": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "hitratePct": {
                "type": "number",
                "nullable": true
              }
            },
            "required": [
              "sentCount",
              "sentNetCents",
              "acceptedCount",
              "acceptedNetCents",
              "declinedCount",
              "hitratePct"
            ]
          }
        },
        "required": [
          "months",
          "totals"
        ]
      },
      "QuoteViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "displayKey": {
            "type": "string"
          },
          "customerId": {
            "type": "string"
          },
          "customerName": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "language": {
            "type": "string",
            "enum": [
              "fi",
              "sv",
              "en"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "sent",
              "accepted",
              "declined",
              "expired"
            ]
          },
          "validUntil": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "introText": {
            "type": "string",
            "nullable": true
          },
          "termsText": {
            "type": "string",
            "nullable": true
          },
          "totalNetCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "totalVatCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "totalGrossCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "vatGroups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "vatRate": {
                  "type": "number"
                },
                "netCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "vatRate",
                "netCents",
                "vatCents"
              ]
            }
          },
          "sentAt": {
            "type": "string",
            "nullable": true
          },
          "decidedAt": {
            "type": "string",
            "nullable": true
          },
          "deciderName": {
            "type": "string",
            "nullable": true
          },
          "decisionComment": {
            "type": "string",
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "nullable": true
          },
          "projectName": {
            "type": "string",
            "nullable": true
          },
          "dealId": {
            "type": "string",
            "nullable": true
          },
          "dealTitle": {
            "type": "string",
            "nullable": true
          },
          "contactId": {
            "type": "string",
            "nullable": true
          },
          "contactName": {
            "type": "string",
            "nullable": true
          },
          "hasActiveShare": {
            "type": "boolean"
          },
          "defaultWorkPriceCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "defaultWorkCostCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "templateName": {
            "type": "string",
            "nullable": true
          },
          "sections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "title",
                "sortOrder"
              ]
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "sectionId": {
                  "type": "string",
                  "nullable": true
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "work",
                    "item",
                    "expense"
                  ]
                },
                "description": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "unit": {
                  "type": "string"
                },
                "unitPriceCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatRate": {
                  "type": "number"
                },
                "discountPct": {
                  "type": "number",
                  "nullable": true
                },
                "unitCostCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "netCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "sectionId",
                "sortOrder",
                "kind",
                "description",
                "quantity",
                "unit",
                "unitPriceCents",
                "vatRate",
                "discountPct",
                "unitCostCents",
                "netCents"
              ]
            }
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "actorName": {
                  "type": "string",
                  "nullable": true
                },
                "comment": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "type",
                "actorName",
                "comment",
                "createdAt"
              ]
            }
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "number",
          "displayKey",
          "customerId",
          "customerName",
          "title",
          "language",
          "status",
          "validUntil",
          "introText",
          "termsText",
          "totalNetCents",
          "totalVatCents",
          "totalGrossCents",
          "vatGroups",
          "sentAt",
          "decidedAt",
          "deciderName",
          "decisionComment",
          "projectId",
          "projectName",
          "dealId",
          "dealTitle",
          "contactId",
          "contactName",
          "hasActiveShare",
          "defaultWorkPriceCents",
          "defaultWorkCostCents",
          "templateName",
          "sections",
          "lines",
          "events",
          "createdAt",
          "updatedAt"
        ]
      },
      "SendQuoteDto": {
        "type": "object",
        "properties": {
          "recipientEmail": {
            "type": "string",
            "format": "email",
            "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
          },
          "recipientName": {
            "type": "string",
            "maxLength": 200
          },
          "message": {
            "type": "string",
            "maxLength": 2000
          }
        }
      },
      "SendQuoteResponseDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "emailed": {
            "type": "boolean"
          }
        },
        "required": [
          "url",
          "emailed"
        ]
      },
      "ConvertQuoteDto": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
          },
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "billingModel": {
            "default": "fixed_price",
            "type": "string",
            "enum": [
              "fixed_price",
              "time_materials"
            ]
          },
          "startDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "endDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "createInstallmentsFromSections": {
            "default": false,
            "type": "boolean"
          }
        }
      },
      "BalanceAccountsResponseDto": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "accountTypeId": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "flex",
                    "overtime_bank",
                    "worktime_bank",
                    "shorter_worktime"
                  ]
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "totalMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "within-limits",
                    "over-max",
                    "under-min"
                  ]
                },
                "capMaxMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "capMinMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "plannedDrawMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "accountTypeId",
                "kind",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "totalMinutes",
                "status",
                "capMaxMinutes",
                "capMinMinutes"
              ]
            }
          }
        },
        "required": [
          "accounts"
        ]
      },
      "BulkCreateCustomersDto": {
        "type": "object",
        "properties": {
          "rows": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "businessId": {
                  "type": "string",
                  "maxLength": 20
                },
                "einvoiceAddress": {
                  "type": "string",
                  "maxLength": 50
                },
                "einvoiceOperator": {
                  "type": "string",
                  "maxLength": 50
                },
                "invoiceReference": {
                  "type": "string",
                  "maxLength": 50
                }
              },
              "required": [
                "name"
              ]
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "BulkImportResponseDto": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "skipped",
                    "error"
                  ]
                },
                "id": {
                  "type": "string",
                  "nullable": true
                },
                "code": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "index",
                "status",
                "id",
                "code"
              ]
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "BulkCreateProjectsDto": {
        "type": "object",
        "properties": {
          "rows": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "customerCode": {
                  "type": "string",
                  "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
                },
                "customerName": {
                  "type": "string",
                  "maxLength": 200
                },
                "ownerEmail": {
                  "type": "string",
                  "format": "email",
                  "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "endDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "budgetMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "budgetAmountCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "billingModel": {
                  "type": "string",
                  "enum": [
                    "time_materials",
                    "fixed_price",
                    "non_billable",
                    "retainer"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "active",
                    "on_hold",
                    "closed"
                  ]
                }
              },
              "required": [
                "name"
              ]
            }
          },
          "createMissingCustomers": {
            "default": false,
            "type": "boolean"
          }
        },
        "required": [
          "rows"
        ]
      },
      "BulkCreateTasksDto": {
        "type": "object",
        "properties": {
          "rows": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "projectCode": {
                  "type": "string",
                  "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
                },
                "title": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "description": {
                  "type": "string",
                  "maxLength": 8000
                },
                "assigneeEmail": {
                  "type": "string",
                  "format": "email",
                  "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                },
                "startDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "dueDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "estimateMinutes": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "priority": {
                  "type": "string",
                  "enum": [
                    "low",
                    "normal",
                    "high",
                    "urgent"
                  ]
                },
                "done": {
                  "type": "boolean"
                }
              },
              "required": [
                "projectCode",
                "title"
              ]
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "BulkCreateLeadsDto": {
        "type": "object",
        "properties": {
          "rows": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "companyName": {
                  "type": "string",
                  "maxLength": 200
                },
                "businessId": {
                  "type": "string",
                  "maxLength": 20
                },
                "personName": {
                  "type": "string",
                  "maxLength": 200
                },
                "email": {
                  "type": "string",
                  "maxLength": 200,
                  "format": "email",
                  "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                },
                "phone": {
                  "type": "string",
                  "maxLength": 50
                },
                "notes": {
                  "type": "string",
                  "maxLength": 4000
                },
                "source": {
                  "default": "import",
                  "type": "string",
                  "enum": [
                    "manual",
                    "intake",
                    "import",
                    "website",
                    "referral",
                    "other"
                  ]
                }
              },
              "required": [
                "title"
              ]
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "BulkImportWithDuplicatesResponseDto": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "skipped",
                    "error"
                  ]
                },
                "id": {
                  "type": "string",
                  "nullable": true
                },
                "code": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "index",
                "status",
                "id",
                "code"
              ]
            }
          },
          "duplicates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "email",
                    "title_company"
                  ]
                },
                "existingId": {
                  "type": "string"
                }
              },
              "required": [
                "index",
                "reason",
                "existingId"
              ]
            }
          }
        },
        "required": [
          "results",
          "duplicates"
        ]
      },
      "BulkCreateContactsDto": {
        "type": "object",
        "properties": {
          "rows": {
            "minItems": 1,
            "maxItems": 500,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "customerCode": {
                  "type": "string",
                  "pattern": "^[a-z0-9][a-z0-9_-]{0,49}$"
                },
                "firstName": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "lastName": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "title": {
                  "type": "string",
                  "maxLength": 100
                },
                "email": {
                  "type": "string",
                  "maxLength": 200,
                  "format": "email",
                  "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                },
                "phone": {
                  "type": "string",
                  "maxLength": 50
                },
                "role": {
                  "type": "string",
                  "maxLength": 100
                },
                "isPrimary": {
                  "type": "boolean"
                }
              },
              "required": [
                "customerCode",
                "firstName",
                "lastName"
              ]
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "IntakeListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "details": {
                  "type": "string",
                  "nullable": true
                },
                "customerId": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                },
                "requesterName": {
                  "type": "string",
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "new",
                    "accepted",
                    "dismissed"
                  ]
                },
                "createdByName": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "resolvedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "projectId": {
                  "type": "string",
                  "nullable": true
                },
                "taskId": {
                  "type": "string",
                  "nullable": true
                },
                "leadId": {
                  "type": "string",
                  "nullable": true
                },
                "dismissReason": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "title",
                "details",
                "customerId",
                "customerName",
                "requesterName",
                "status",
                "createdByName",
                "createdAt",
                "resolvedAt",
                "projectId",
                "taskId",
                "leadId",
                "dismissReason"
              ]
            }
          },
          "newCount": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "truncated": {
            "type": "boolean"
          }
        },
        "required": [
          "items",
          "newCount",
          "truncated"
        ]
      },
      "CreateIntakeItemDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "details": {
            "type": "string",
            "maxLength": 2000,
            "nullable": true
          },
          "customerId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "requesterName": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          }
        },
        "required": [
          "title"
        ]
      },
      "IntakeItemViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "details": {
            "type": "string",
            "nullable": true
          },
          "customerId": {
            "type": "string",
            "nullable": true
          },
          "customerName": {
            "type": "string",
            "nullable": true
          },
          "requesterName": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "accepted",
              "dismissed"
            ]
          },
          "createdByName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "projectId": {
            "type": "string",
            "nullable": true
          },
          "taskId": {
            "type": "string",
            "nullable": true
          },
          "leadId": {
            "type": "string",
            "nullable": true
          },
          "dismissReason": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "title",
          "details",
          "customerId",
          "customerName",
          "requesterName",
          "status",
          "createdByName",
          "createdAt",
          "resolvedAt",
          "projectId",
          "taskId",
          "leadId",
          "dismissReason"
        ]
      },
      "AcceptIntakeItemDto": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "projectId"
        ]
      },
      "RouteIntakeToLeadDto": {
        "type": "object",
        "properties": {
          "ownerMembershipId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        }
      },
      "DismissIntakeItemDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "nullable": true
          }
        }
      },
      "ChangeOrderListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "number": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "pricing": {
                  "type": "string",
                  "enum": [
                    "fixed",
                    "time_materials"
                  ]
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "pending",
                    "approved",
                    "declined"
                  ]
                },
                "approvedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "approverContactId": {
                  "type": "string",
                  "nullable": true
                },
                "approverContactName": {
                  "type": "string",
                  "nullable": true
                },
                "approverName": {
                  "type": "string",
                  "nullable": true
                },
                "approvalComment": {
                  "type": "string",
                  "nullable": true
                },
                "approvedVia": {
                  "type": "string",
                  "enum": [
                    "link",
                    "manual",
                    null
                  ],
                  "nullable": true
                },
                "readyAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "invoiceState": {
                  "type": "string",
                  "enum": [
                    "none",
                    "draft_invoice",
                    "invoiced"
                  ]
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                }
              },
              "required": [
                "id",
                "number",
                "title",
                "description",
                "pricing",
                "amountCents",
                "status",
                "approvedAt",
                "approverContactId",
                "approverContactName",
                "approverName",
                "approvalComment",
                "approvedVia",
                "readyAt",
                "invoiceState",
                "createdAt"
              ]
            }
          },
          "approvedCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "pendingCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "items",
          "approvedCents",
          "pendingCents"
        ]
      },
      "CreateChangeOrderDto": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 4000,
            "nullable": true
          },
          "pricing": {
            "default": "fixed",
            "type": "string",
            "enum": [
              "fixed",
              "time_materials"
            ]
          },
          "amountCents": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          }
        },
        "required": [
          "title"
        ]
      },
      "ChangeOrderViewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "pricing": {
            "type": "string",
            "enum": [
              "fixed",
              "time_materials"
            ]
          },
          "amountCents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "pending",
              "approved",
              "declined"
            ]
          },
          "approvedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "approverContactId": {
            "type": "string",
            "nullable": true
          },
          "approverContactName": {
            "type": "string",
            "nullable": true
          },
          "approverName": {
            "type": "string",
            "nullable": true
          },
          "approvalComment": {
            "type": "string",
            "nullable": true
          },
          "approvedVia": {
            "type": "string",
            "enum": [
              "link",
              "manual",
              null
            ],
            "nullable": true
          },
          "readyAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
            "nullable": true
          },
          "invoiceState": {
            "type": "string",
            "enum": [
              "none",
              "draft_invoice",
              "invoiced"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "description",
          "pricing",
          "amountCents",
          "status",
          "approvedAt",
          "approverContactId",
          "approverContactName",
          "approverName",
          "approvalComment",
          "approvedVia",
          "readyAt",
          "invoiceState",
          "createdAt"
        ]
      },
      "ApproveChangeOrderDto": {
        "type": "object",
        "properties": {
          "approverName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "approverContactId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "comment": {
            "type": "string",
            "maxLength": 2000,
            "nullable": true
          }
        },
        "required": [
          "approverName"
        ]
      },
      "SearchResponseDto": {
        "type": "object",
        "properties": {
          "people": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "displayName": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "employee",
                    "manager",
                    "admin",
                    "payroll",
                    "hr"
                  ]
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "email",
                "role"
              ]
            }
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "name": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "name",
                "code",
                "customerName"
              ]
            }
          },
          "tasks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "title": {
                  "type": "string"
                },
                "number": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "projectId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "projectCode": {
                  "type": "string"
                },
                "projectName": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "title",
                "number",
                "projectId",
                "projectCode",
                "projectName"
              ]
            }
          },
          "customers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "name": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "active": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "name",
                "code",
                "active"
              ]
            }
          },
          "quotes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "title": {
                  "type": "string"
                },
                "displayKey": {
                  "type": "string"
                },
                "customerName": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "title",
                "displayKey",
                "customerName"
              ]
            }
          },
          "tesRulesets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "key": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "key",
                "nameFi",
                "nameSv",
                "nameEn"
              ]
            }
          },
          "deals": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "title": {
                  "type": "string"
                },
                "customerId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "customerName": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "title",
                "customerId",
                "customerName"
              ]
            }
          },
          "leads": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "title": {
                  "type": "string"
                },
                "companyName": {
                  "type": "string",
                  "nullable": true
                },
                "personName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "title",
                "companyName",
                "personName"
              ]
            }
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "customerId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "firstName": {
                  "type": "string",
                  "nullable": true
                },
                "lastName": {
                  "type": "string",
                  "nullable": true
                },
                "email": {
                  "type": "string",
                  "nullable": true
                },
                "customerName": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "customerId",
                "firstName",
                "lastName",
                "email",
                "customerName"
              ]
            }
          },
          "activities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "subject": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "call",
                    "meeting",
                    "email",
                    "note",
                    "task"
                  ]
                },
                "customerId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "dealId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                  "nullable": true
                },
                "customerName": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "subject",
                "type",
                "customerId",
                "dealId",
                "customerName"
              ]
            }
          }
        },
        "required": [
          "people",
          "projects",
          "tasks",
          "customers",
          "quotes",
          "tesRulesets",
          "deals",
          "leads",
          "contacts",
          "activities"
        ]
      },
      "ExpenseTypeListResponseDto": {
        "type": "object",
        "properties": {
          "expenseTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "actual",
                    "unit_rate",
                    "tes"
                  ]
                },
                "unit": {
                  "type": "string",
                  "enum": [
                    "piece",
                    "km",
                    "day"
                  ]
                },
                "rateKey": {
                  "type": "string",
                  "nullable": true
                },
                "defaultReimbursable": {
                  "type": "boolean"
                },
                "defaultBillable": {
                  "type": "boolean"
                },
                "taxFree": {
                  "type": "boolean"
                },
                "payComponentCode": {
                  "type": "string",
                  "nullable": true
                },
                "glAccount": {
                  "type": "string",
                  "nullable": true
                },
                "vatRate": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "vatDeductible": {
                  "type": "boolean"
                },
                "reportingClass": {
                  "type": "string",
                  "enum": [
                    "reported_tax_free",
                    "reported_taxable",
                    "not_reported"
                  ]
                },
                "incomeType": {
                  "type": "string",
                  "nullable": true
                },
                "active": {
                  "type": "boolean"
                },
                "isSystem": {
                  "type": "boolean"
                },
                "locked": {
                  "type": "boolean"
                },
                "sortOrder": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "code",
                "nameFi",
                "nameSv",
                "nameEn",
                "kind",
                "unit",
                "rateKey",
                "defaultReimbursable",
                "defaultBillable",
                "taxFree",
                "payComponentCode",
                "glAccount",
                "vatRate",
                "vatDeductible",
                "reportingClass",
                "incomeType",
                "active",
                "isSystem",
                "locked",
                "sortOrder"
              ]
            }
          }
        },
        "required": [
          "expenseTypes"
        ]
      },
      "ExpenseIdResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "ExpenseOkResponseDto": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ]
      },
      "ExpenseListResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "membershipId": {
                  "type": "string"
                },
                "memberName": {
                  "type": "string"
                },
                "expenseDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "type": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "nameFi": {
                      "type": "string"
                    },
                    "nameSv": {
                      "type": "string"
                    },
                    "nameEn": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "actual",
                        "unit_rate",
                        "tes"
                      ]
                    },
                    "unit": {
                      "type": "string",
                      "enum": [
                        "piece",
                        "km",
                        "day"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "nameFi",
                    "nameSv",
                    "nameEn",
                    "kind",
                    "unit"
                  ]
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "quantity": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "amountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "vatBreakdown": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "rateBps": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 10000
                      },
                      "grossCents": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      },
                      "vatCents": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 9007199254740991
                      }
                    },
                    "required": [
                      "rateBps",
                      "grossCents",
                      "vatCents"
                    ]
                  },
                  "nullable": true
                },
                "paidBy": {
                  "type": "string",
                  "enum": [
                    "company",
                    "employee"
                  ]
                },
                "reimbursable": {
                  "type": "boolean"
                },
                "billable": {
                  "type": "boolean"
                },
                "billableAmountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "billingMode": {
                  "type": "string",
                  "enum": [
                    "billable_amount",
                    "cost",
                    "cost_multiplier",
                    "manual"
                  ]
                },
                "billingMultiplierPermille": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "valueName": {
                  "type": "string",
                  "nullable": true
                },
                "allocations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "dimensionId": {
                        "type": "string"
                      },
                      "valueId": {
                        "type": "string"
                      },
                      "valueName": {
                        "type": "string",
                        "nullable": true
                      }
                    },
                    "required": [
                      "dimensionId",
                      "valueId",
                      "valueName"
                    ]
                  }
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "submitted",
                    "reviewed",
                    "approved"
                  ]
                },
                "submittedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "nullable": true
                },
                "returnReason": {
                  "type": "string",
                  "nullable": true
                },
                "tripId": {
                  "type": "string",
                  "nullable": true
                },
                "tripDayId": {
                  "type": "string",
                  "nullable": true
                },
                "maxTaxFreeCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "originalCurrency": {
                  "type": "string",
                  "nullable": true
                },
                "originalAmountCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                },
                "mileage": {
                  "type": "object",
                  "properties": {
                    "kmHundredths": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "fromText": {
                      "type": "string",
                      "nullable": true
                    },
                    "toText": {
                      "type": "string",
                      "nullable": true
                    },
                    "roundTrip": {
                      "type": "boolean"
                    },
                    "additions": {
                      "type": "object",
                      "properties": {
                        "passengers": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9
                        },
                        "trailer": {
                          "type": "boolean"
                        },
                        "caravan": {
                          "type": "boolean"
                        },
                        "heavyLoad": {
                          "type": "boolean"
                        },
                        "machine": {
                          "type": "boolean"
                        },
                        "dog": {
                          "type": "boolean"
                        },
                        "forest": {
                          "type": "boolean"
                        }
                      },
                      "nullable": true
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "manual",
                        "route",
                        "odometer",
                        "gps"
                      ]
                    },
                    "route": {
                      "type": "object",
                      "properties": {
                        "fromPlace": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 160
                            },
                            "lat": {
                              "type": "number",
                              "minimum": -90,
                              "maximum": 90
                            },
                            "lon": {
                              "type": "number",
                              "minimum": -180,
                              "maximum": 180
                            }
                          },
                          "required": [
                            "text"
                          ]
                        },
                        "toPlace": {
                          "type": "object",
                          "properties": {
                            "text": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 160
                            },
                            "lat": {
                              "type": "number",
                              "minimum": -90,
                              "maximum": 90
                            },
                            "lon": {
                              "type": "number",
                              "minimum": -180,
                              "maximum": 180
                            }
                          },
                          "required": [
                            "text"
                          ]
                        },
                        "waypoints": {
                          "maxItems": 15,
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "text": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 160
                              },
                              "lat": {
                                "type": "number",
                                "minimum": -90,
                                "maximum": 90
                              },
                              "lon": {
                                "type": "number",
                                "minimum": -180,
                                "maximum": 180
                              }
                            },
                            "required": [
                              "text"
                            ]
                          }
                        },
                        "computedKmHundredths": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "provider": {
                          "type": "string",
                          "maxLength": 40
                        },
                        "alternativeIndex": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "fromPlace",
                        "toPlace",
                        "computedKmHundredths"
                      ],
                      "nullable": true
                    },
                    "odometer": {
                      "type": "object",
                      "properties": {
                        "startKm": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "endKm": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "startKm",
                        "endKm"
                      ],
                      "nullable": true
                    },
                    "vehicleId": {
                      "type": "string",
                      "nullable": true
                    }
                  },
                  "required": [
                    "kmHundredths",
                    "fromText",
                    "toText",
                    "roundTrip",
                    "additions",
                    "source",
                    "route",
                    "odometer",
                    "vehicleId"
                  ],
                  "nullable": true
                },
                "policyFlags": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "over_limit",
                      "receipt_required",
                      "project_required",
                      "meal_allowance_with_per_diem",
                      "possible_duplicate"
                    ]
                  }
                },
                "hasReceipt": {
                  "type": "boolean"
                },
                "exportedAt": {
                  "type": "string",
                  "nullable": true
                },
                "policyMaxPerExpenseCents": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "nullable": true
                }
              },
              "required": [
                "id",
                "membershipId",
                "memberName",
                "expenseDate",
                "type",
                "description",
                "quantity",
                "amountCents",
                "vatCents",
                "vatBreakdown",
                "paidBy",
                "reimbursable",
                "billable",
                "billableAmountCents",
                "dimensionValueId",
                "valueName",
                "allocations",
                "status",
                "submittedAt",
                "returnReason",
                "tripId",
                "tripDayId",
                "maxTaxFreeCents",
                "originalCurrency",
                "originalAmountCents",
                "mileage",
                "policyFlags",
                "hasReceipt",
                "exportedAt",
                "policyMaxPerExpenseCents"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "CreateExpenseDto": {
        "type": "object",
        "properties": {
          "expenseTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "expenseDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "quantity": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "amountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "vatCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "vatBreakdown": {
            "maxItems": 4,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rateBps": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 10000
                },
                "grossCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "rateBps",
                "grossCents",
                "vatCents"
              ]
            },
            "nullable": true
          },
          "paidBy": {
            "type": "string",
            "enum": [
              "company",
              "employee"
            ]
          },
          "reimbursable": {
            "type": "boolean"
          },
          "billable": {
            "type": "boolean"
          },
          "billableAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "billingMode": {
            "type": "string",
            "enum": [
              "billable_amount",
              "cost",
              "cost_multiplier",
              "manual"
            ]
          },
          "billingMultiplierPermille": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000,
            "nullable": true
          },
          "dimensionValueId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "allocations": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "tripId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "tripDayId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "originalCurrency": {
            "type": "string",
            "pattern": "^[A-Za-z]{3}$",
            "nullable": true
          },
          "originalAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "mileage": {
            "type": "object",
            "properties": {
              "kmHundredths": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "fromText": {
                "type": "string",
                "maxLength": 120
              },
              "toText": {
                "type": "string",
                "maxLength": 120
              },
              "roundTrip": {
                "type": "boolean"
              },
              "additions": {
                "type": "object",
                "properties": {
                  "passengers": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9
                  },
                  "trailer": {
                    "type": "boolean"
                  },
                  "caravan": {
                    "type": "boolean"
                  },
                  "heavyLoad": {
                    "type": "boolean"
                  },
                  "machine": {
                    "type": "boolean"
                  },
                  "dog": {
                    "type": "boolean"
                  },
                  "forest": {
                    "type": "boolean"
                  }
                }
              },
              "source": {
                "type": "string",
                "enum": [
                  "manual",
                  "route",
                  "odometer",
                  "gps"
                ]
              },
              "route": {
                "type": "object",
                "properties": {
                  "fromPlace": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 160
                      },
                      "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      "lon": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      }
                    },
                    "required": [
                      "text"
                    ]
                  },
                  "toPlace": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 160
                      },
                      "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      "lon": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      }
                    },
                    "required": [
                      "text"
                    ]
                  },
                  "waypoints": {
                    "maxItems": 15,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 160
                        },
                        "lat": {
                          "type": "number",
                          "minimum": -90,
                          "maximum": 90
                        },
                        "lon": {
                          "type": "number",
                          "minimum": -180,
                          "maximum": 180
                        }
                      },
                      "required": [
                        "text"
                      ]
                    }
                  },
                  "computedKmHundredths": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "provider": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "alternativeIndex": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "fromPlace",
                  "toPlace",
                  "computedKmHundredths"
                ]
              },
              "odometer": {
                "type": "object",
                "properties": {
                  "startKm": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "endKm": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "startKm",
                  "endKm"
                ]
              },
              "vehicleId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              }
            },
            "required": [
              "kmHundredths"
            ]
          }
        },
        "required": [
          "expenseTypeId",
          "expenseDate"
        ]
      },
      "UpdateExpenseDto": {
        "type": "object",
        "properties": {
          "expenseTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "expenseDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "quantity": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "amountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "vatCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "vatBreakdown": {
            "maxItems": 4,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "rateBps": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 10000
                },
                "grossCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "vatCents": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "rateBps",
                "grossCents",
                "vatCents"
              ]
            },
            "nullable": true
          },
          "paidBy": {
            "type": "string",
            "enum": [
              "company",
              "employee"
            ]
          },
          "reimbursable": {
            "type": "boolean"
          },
          "billable": {
            "type": "boolean"
          },
          "billableAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "billingMode": {
            "type": "string",
            "enum": [
              "billable_amount",
              "cost",
              "cost_multiplier",
              "manual"
            ]
          },
          "billingMultiplierPermille": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000,
            "nullable": true
          },
          "dimensionValueId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "allocations": {
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "tripId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "tripDayId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
            "nullable": true
          },
          "originalCurrency": {
            "type": "string",
            "pattern": "^[A-Za-z]{3}$",
            "nullable": true
          },
          "originalAmountCents": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "nullable": true
          },
          "mileage": {
            "type": "object",
            "properties": {
              "kmHundredths": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "fromText": {
                "type": "string",
                "maxLength": 120
              },
              "toText": {
                "type": "string",
                "maxLength": 120
              },
              "roundTrip": {
                "type": "boolean"
              },
              "additions": {
                "type": "object",
                "properties": {
                  "passengers": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9
                  },
                  "trailer": {
                    "type": "boolean"
                  },
                  "caravan": {
                    "type": "boolean"
                  },
                  "heavyLoad": {
                    "type": "boolean"
                  },
                  "machine": {
                    "type": "boolean"
                  },
                  "dog": {
                    "type": "boolean"
                  },
                  "forest": {
                    "type": "boolean"
                  }
                }
              },
              "source": {
                "type": "string",
                "enum": [
                  "manual",
                  "route",
                  "odometer",
                  "gps"
                ]
              },
              "route": {
                "type": "object",
                "properties": {
                  "fromPlace": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 160
                      },
                      "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      "lon": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      }
                    },
                    "required": [
                      "text"
                    ]
                  },
                  "toPlace": {
                    "type": "object",
                    "properties": {
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 160
                      },
                      "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      "lon": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      }
                    },
                    "required": [
                      "text"
                    ]
                  },
                  "waypoints": {
                    "maxItems": 15,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 160
                        },
                        "lat": {
                          "type": "number",
                          "minimum": -90,
                          "maximum": 90
                        },
                        "lon": {
                          "type": "number",
                          "minimum": -180,
                          "maximum": 180
                        }
                      },
                      "required": [
                        "text"
                      ]
                    }
                  },
                  "computedKmHundredths": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "provider": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "alternativeIndex": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "fromPlace",
                  "toPlace",
                  "computedKmHundredths"
                ]
              },
              "odometer": {
                "type": "object",
                "properties": {
                  "startKm": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "endKm": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "startKm",
                  "endKm"
                ]
              },
              "vehicleId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              }
            },
            "required": [
              "kmHundredths"
            ]
          }
        }
      },
      "ReturnExpenseDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          }
        },
        "required": [
          "reason"
        ]
      },
      "PunchSessionStateDto": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "open": {
            "type": "boolean"
          },
          "onBreak": {
            "type": "boolean"
          },
          "workDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "nullable": true
          },
          "workMinutesSoFar": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "breakMinutesSoFar": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "completedBreakMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "breakStartedAt": {
            "type": "string",
            "nullable": true
          },
          "entryTypeId": {
            "type": "string",
            "nullable": true
          },
          "allocations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "weightBp": {
                  "default": 10000,
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 10000
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "task": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "taskKey": {
                "type": "string"
              },
              "title": {
                "type": "string"
              },
              "projectId": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "taskKey",
              "title",
              "projectId"
            ],
            "nullable": true
          },
          "source": {
            "type": "string",
            "enum": [
              "web",
              "mobile",
              "device",
              "system",
              null
            ],
            "nullable": true
          },
          "locationCapture": {
            "type": "string",
            "enum": [
              "off",
              "site",
              "geofence",
              "coordinates"
            ]
          },
          "locationRequired": {
            "type": "boolean"
          },
          "locationPurposeTextFi": {
            "type": "string",
            "nullable": true
          },
          "locationPurposeTextSv": {
            "type": "string",
            "nullable": true
          },
          "locationPurposeTextEn": {
            "type": "string",
            "nullable": true
          },
          "sites": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "dimensionValueId": {
                  "type": "string",
                  "nullable": true
                },
                "nameFi": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameSv": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "nameEn": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "latitude": {
                  "type": "number"
                },
                "longitude": {
                  "type": "number"
                },
                "radiusM": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "id",
                "dimensionValueId",
                "nameFi",
                "nameSv",
                "nameEn",
                "latitude",
                "longitude",
                "radiusM"
              ]
            }
          },
          "prompts": {
            "type": "object",
            "properties": {
              "entryType": {
                "type": "string",
                "enum": [
                  "hidden",
                  "optional",
                  "required"
                ]
              },
              "allocations": {
                "type": "string",
                "enum": [
                  "hidden",
                  "optional",
                  "required"
                ]
              },
              "billable": {
                "type": "string",
                "enum": [
                  "hidden",
                  "optional",
                  "required"
                ]
              },
              "note": {
                "type": "string",
                "enum": [
                  "hidden",
                  "optional",
                  "required"
                ]
              },
              "clockOutReason": {
                "type": "string",
                "enum": [
                  "hidden",
                  "optional",
                  "required"
                ]
              }
            },
            "required": [
              "entryType",
              "allocations",
              "billable",
              "note",
              "clockOutReason"
            ]
          },
          "backdatedPunchAllowed": {
            "default": true,
            "type": "boolean"
          },
          "backdatedPunchMaxHours": {
            "default": 72,
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991
          },
          "forgottenSessionAfterMinutes": {
            "default": 720,
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "returnGap": {
            "type": "object",
            "properties": {
              "fromDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "toDate": {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "workdayCount": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "fromDate",
              "toDate",
              "workdayCount"
            ],
            "default": null,
            "nullable": true
          },
          "noted": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "occurredAt": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "occurredAt"
            ],
            "default": null,
            "nullable": true
          }
        },
        "required": [
          "enabled",
          "open",
          "onBreak",
          "workDate",
          "startedAt",
          "workMinutesSoFar",
          "breakMinutesSoFar",
          "completedBreakMinutes",
          "breakStartedAt",
          "entryTypeId",
          "allocations",
          "task",
          "source",
          "locationCapture",
          "locationRequired",
          "locationPurposeTextFi",
          "locationPurposeTextSv",
          "locationPurposeTextEn",
          "sites",
          "prompts"
        ]
      },
      "ClockInDto": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "web",
              "mobile"
            ]
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "occurredAtSource": {
            "type": "string",
            "enum": [
              "captured",
              "entered"
            ]
          },
          "entryTypeId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "allocations": {
            "maxItems": 10,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "weightBp": {
                  "default": 10000,
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 10000
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "taskId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "billable": {
            "type": "boolean"
          },
          "note": {
            "type": "string",
            "maxLength": 500
          },
          "location": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "site",
                  "geofence",
                  "coordinates"
                ]
              },
              "siteId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "qrToken": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "latitude": {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              },
              "longitude": {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              },
              "accuracyMeters": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "mode"
            ]
          },
          "clientPunchId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "source"
        ]
      },
      "PunchMarkDto": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "web",
              "mobile"
            ]
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          },
          "occurredAtSource": {
            "type": "string",
            "enum": [
              "captured",
              "entered"
            ]
          },
          "location": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "site",
                  "geofence",
                  "coordinates"
                ]
              },
              "siteId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "qrToken": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "latitude": {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              },
              "longitude": {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              },
              "accuracyMeters": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "mode"
            ]
          },
          "reasonId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "expectedReturnDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "paid": {
            "type": "boolean"
          },
          "clientPunchId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        },
        "required": [
          "source"
        ]
      },
      "RecordAbsenceGapDto": {
        "type": "object",
        "properties": {
          "reasonId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "fromDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "toDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          }
        },
        "required": [
          "reasonId",
          "fromDate",
          "toDate"
        ]
      },
      "SetPunchAllocationDto": {
        "type": "object",
        "properties": {
          "allocations": {
            "maxItems": 10,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dimensionId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "valueId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "weightBp": {
                  "default": 10000,
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 10000
                }
              },
              "required": [
                "dimensionId",
                "valueId"
              ]
            }
          },
          "taskId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          }
        }
      },
      "PunchDayViewDto": {
        "type": "object",
        "properties": {
          "workDate": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "clock_in",
                    "clock_out",
                    "break_start",
                    "break_end"
                  ]
                },
                "atMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 2880
                },
                "occurredAt": {
                  "type": "string"
                },
                "occurredAtSource": {
                  "type": "string",
                  "enum": [
                    "captured",
                    "entered"
                  ]
                },
                "recordedAt": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "web",
                    "mobile",
                    "device",
                    "system"
                  ]
                },
                "atSite": {
                  "type": "boolean",
                  "nullable": true
                },
                "reasonId": {
                  "type": "string",
                  "nullable": true
                },
                "paid": {
                  "type": "boolean",
                  "nullable": true
                },
                "noteCode": {
                  "type": "string",
                  "nullable": true
                },
                "counted": {
                  "type": "boolean"
                }
              },
              "required": [
                "kind",
                "atMinutes",
                "occurredAt",
                "occurredAtSource",
                "recordedAt",
                "source",
                "atSite",
                "reasonId",
                "paid",
                "noteCode",
                "counted"
              ]
            }
          },
          "punchedStartMinutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2880,
            "nullable": true
          },
          "punchedEndMinutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2880,
            "nullable": true
          },
          "punchedWorkMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "punchedBreakMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "punchedPaidBreakMinutes": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "anomalies": {
            "default": [],
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "out_of_range",
                "non_monotonic",
                "duplicate_clock_in",
                "clock_out_without_session",
                "break_without_session",
                "duplicate_break_start",
                "break_end_without_break",
                "open_session",
                "dst_repeated_hour",
                "overlap"
              ]
            }
          },
          "lockedPunchCount": {
            "default": 0,
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "workDate",
          "events",
          "punchedStartMinutes",
          "punchedEndMinutes",
          "punchedWorkMinutes",
          "punchedBreakMinutes",
          "punchedPaidBreakMinutes"
        ]
      },
      "TeamPresenceViewDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "open": {
                  "type": "boolean"
                },
                "onBreak": {
                  "type": "boolean"
                },
                "startedAt": {
                  "type": "string",
                  "nullable": true
                },
                "workMinutesSoFar": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "atSite": {
                  "type": "boolean",
                  "nullable": true
                },
                "sincePreviousDay": {
                  "default": false,
                  "type": "boolean"
                },
                "workDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "default": null,
                  "nullable": true
                },
                "openMinutes": {
                  "default": 0,
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "open",
                "onBreak",
                "startedAt",
                "workMinutesSoFar",
                "atSite"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          },
          "coverage": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "requirementId": {
                  "type": "string"
                },
                "planningUnitId": {
                  "type": "string"
                },
                "planningUnitName": {
                  "type": "string"
                },
                "startMinutes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1440
                },
                "endMinutes": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2880
                },
                "requiredCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "positionId": {
                  "type": "string",
                  "nullable": true
                },
                "presentCount": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                },
                "shortfall": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991
                }
              },
              "required": [
                "requirementId",
                "planningUnitId",
                "planningUnitName",
                "startMinutes",
                "endMinutes",
                "requiredCount",
                "positionId",
                "presentCount",
                "shortfall"
              ]
            }
          },
          "absences": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "membershipId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "nameFi": {
                  "type": "string"
                },
                "nameSv": {
                  "type": "string"
                },
                "nameEn": {
                  "type": "string"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "leave",
                    "punch_intent"
                  ]
                },
                "expectedReturnDate": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                  "nullable": true
                }
              },
              "required": [
                "membershipId",
                "displayName",
                "nameFi",
                "nameSv",
                "nameEn",
                "source",
                "expectedReturnDate"
              ]
            }
          }
        },
        "required": [
          "items",
          "pageInfo"
        ]
      },
      "PayrollPeriodLockListResponseDto": {
        "type": "object",
        "properties": {
          "locks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "periodStart": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "periodEnd": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "lockedByName": {
                  "type": "string",
                  "nullable": true
                },
                "lockedAt": {
                  "type": "string"
                },
                "liftedAt": {
                  "type": "string",
                  "nullable": true
                },
                "liftedByName": {
                  "type": "string",
                  "nullable": true
                },
                "liftReason": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "periodStart",
                "periodEnd",
                "note",
                "lockedByName",
                "lockedAt",
                "liftedAt",
                "liftedByName",
                "liftReason"
              ]
            }
          }
        },
        "required": [
          "locks"
        ]
      },
      "PublicReportTypesResponseDto": {
        "type": "object",
        "properties": {
          "types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "personal-time",
                "team-period",
                "team-absence",
                "overtime-balance",
                "missing-entries",
                "punch-log",
                "inspection",
                "supplement-breakdown",
                "exceptions",
                "staffing-coverage",
                "open-shift-activity",
                "gap-fill-activity",
                "projects",
                "tasks",
                "project-allocations",
                "project-realization",
                "project-utilization",
                "leave-balances",
                "leave-liability",
                "leave-bookkeeping",
                "travel-summary",
                "driving-log",
                "hr",
                "qualification-matrix",
                "corrections",
                "payroll-comparison",
                "schedule-adherence",
                "roster-compliance",
                "plan-vs-actual",
                "publish-compliance"
              ]
            }
          }
        },
        "required": [
          "types"
        ]
      },
      "ApprovalQueueResponseDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "work_week",
                    "expense",
                    "trip",
                    "leave",
                    "swap",
                    "training",
                    "open_shift_claim",
                    "leave_save"
                  ]
                },
                "subject": {
                  "type": "object",
                  "properties": {
                    "membershipId": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "initials": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "membershipId",
                    "name",
                    "initials"
                  ]
                },
                "display": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "work_week"
                          ]
                        },
                        "mondayIso": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "sundayIso": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "dayCount": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "netDeltaMinutes": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "workedMinutes": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "targetMinutes": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "supplementCount": {
                          "default": 0,
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "attentionThresholdMinutes": {
                          "default": 0,
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "appliedCreditMinutes": {
                          "default": 0,
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "weekSignals": {
                          "default": [],
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "insufficient-daily-rest",
                                  "insufficient-weekly-rest",
                                  "weekly-hours-high",
                                  "consecutive-work-days-high"
                                ]
                              },
                              "workDate": {
                                "type": "string",
                                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                              },
                              "value": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991
                              },
                              "limit": {
                                "type": "integer",
                                "minimum": 0,
                                "maximum": 9007199254740991
                              }
                            },
                            "required": [
                              "type",
                              "workDate",
                              "value",
                              "limit"
                            ]
                          }
                        }
                      },
                      "required": [
                        "kind",
                        "mondayIso",
                        "sundayIso",
                        "dayCount",
                        "netDeltaMinutes",
                        "workedMinutes",
                        "targetMinutes"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "expense"
                          ]
                        },
                        "type": {
                          "type": "object",
                          "properties": {
                            "nameFi": {
                              "type": "string"
                            },
                            "nameSv": {
                              "type": "string"
                            },
                            "nameEn": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "nameFi",
                            "nameSv",
                            "nameEn"
                          ]
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "expenseDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "amountCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "vatCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "nullable": true
                        },
                        "paidBy": {
                          "type": "string",
                          "enum": [
                            "company",
                            "employee"
                          ]
                        },
                        "reimbursable": {
                          "type": "boolean"
                        },
                        "billable": {
                          "type": "boolean"
                        },
                        "billableAmountCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "nullable": true
                        },
                        "valueName": {
                          "type": "string",
                          "nullable": true
                        },
                        "allocations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "dimensionId": {
                                "type": "string"
                              },
                              "valueId": {
                                "type": "string"
                              },
                              "valueName": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "dimensionId",
                              "valueId",
                              "valueName"
                            ]
                          }
                        },
                        "maxTaxFreeCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "nullable": true
                        },
                        "originalCurrency": {
                          "type": "string",
                          "nullable": true
                        },
                        "originalAmountCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "nullable": true
                        },
                        "hasReceipt": {
                          "type": "boolean"
                        },
                        "policyMaxPerExpenseCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "nullable": true
                        },
                        "mileage": {
                          "type": "object",
                          "properties": {
                            "fromText": {
                              "type": "string",
                              "nullable": true
                            },
                            "toText": {
                              "type": "string",
                              "nullable": true
                            },
                            "kmHundredths": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "roundTrip": {
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "fromText",
                            "toText",
                            "kmHundredths",
                            "roundTrip"
                          ],
                          "nullable": true
                        }
                      },
                      "required": [
                        "kind",
                        "type",
                        "description",
                        "expenseDate",
                        "amountCents",
                        "vatCents",
                        "paidBy",
                        "reimbursable",
                        "billable",
                        "billableAmountCents",
                        "valueName",
                        "allocations",
                        "maxTaxFreeCents",
                        "originalCurrency",
                        "originalAmountCents",
                        "hasReceipt",
                        "policyMaxPerExpenseCents",
                        "mileage"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "trip"
                          ]
                        },
                        "destination": {
                          "type": "string"
                        },
                        "scope": {
                          "type": "string",
                          "enum": [
                            "domestic",
                            "foreign"
                          ]
                        },
                        "startDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "endDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "dayCount": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "taxFreeTotalCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "taxableTotalCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "reimbursableTotalCents": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "valueName": {
                          "type": "string",
                          "nullable": true
                        },
                        "allocations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "dimensionId": {
                                "type": "string"
                              },
                              "valueId": {
                                "type": "string"
                              },
                              "valueName": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "dimensionId",
                              "valueId",
                              "valueName"
                            ]
                          }
                        },
                        "billable": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "kind",
                        "destination",
                        "scope",
                        "startDate",
                        "endDate",
                        "dayCount",
                        "taxFreeTotalCents",
                        "taxableTotalCents",
                        "reimbursableTotalCents",
                        "valueName",
                        "allocations",
                        "billable"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "leave"
                          ]
                        },
                        "policy": {
                          "type": "object",
                          "properties": {
                            "nameFi": {
                              "type": "string"
                            },
                            "nameSv": {
                              "type": "string"
                            },
                            "nameEn": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "nameFi",
                            "nameSv",
                            "nameEn"
                          ]
                        },
                        "sensitivity": {
                          "type": "string",
                          "enum": [
                            "normal",
                            "restricted",
                            "health"
                          ]
                        },
                        "startDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "endDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "startHalfDay": {
                          "type": "boolean"
                        },
                        "endHalfDay": {
                          "type": "boolean"
                        },
                        "consumesQuarterDays": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "consumesMinutes": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "certificateRequired": {
                          "type": "boolean"
                        },
                        "certificateStatus": {
                          "type": "string",
                          "enum": [
                            "missing",
                            "provided",
                            "waived",
                            null
                          ],
                          "nullable": true
                        }
                      },
                      "required": [
                        "kind",
                        "policy",
                        "sensitivity",
                        "startDate",
                        "endDate",
                        "startHalfDay",
                        "endHalfDay",
                        "consumesQuarterDays",
                        "consumesMinutes",
                        "certificateRequired",
                        "certificateStatus"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "swap"
                          ]
                        },
                        "requesterName": {
                          "type": "string"
                        },
                        "requesterDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "counterpartyMembershipId": {
                          "type": "string",
                          "nullable": true
                        },
                        "counterpartyName": {
                          "type": "string",
                          "nullable": true
                        },
                        "counterpartyDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "nullable": true
                        },
                        "isGiveAway": {
                          "type": "boolean"
                        },
                        "reason": {
                          "type": "string",
                          "nullable": true
                        }
                      },
                      "required": [
                        "kind",
                        "requesterName",
                        "requesterDate",
                        "counterpartyMembershipId",
                        "counterpartyName",
                        "counterpartyDate",
                        "isGiveAway",
                        "reason"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "training"
                          ]
                        },
                        "courseName": {
                          "type": "string"
                        },
                        "justification": {
                          "type": "string"
                        },
                        "costCenter": {
                          "type": "string",
                          "nullable": true
                        },
                        "proposedDate": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                          "nullable": true
                        }
                      },
                      "required": [
                        "kind",
                        "courseName",
                        "justification",
                        "costCenter",
                        "proposedDate"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "open_shift_claim"
                          ]
                        },
                        "date": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "startMinutes": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 1440,
                          "nullable": true
                        },
                        "endMinutes": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 2880,
                          "nullable": true
                        },
                        "unitName": {
                          "type": "string"
                        },
                        "claimantName": {
                          "type": "string"
                        },
                        "otherClaimantCount": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "required": [
                        "kind",
                        "date",
                        "startMinutes",
                        "endMinutes",
                        "unitName",
                        "claimantName",
                        "otherClaimantCount"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "leave_save"
                          ]
                        },
                        "quarterDays": {
                          "type": "integer",
                          "exclusiveMinimum": true,
                          "maximum": 9007199254740991,
                          "minimum": 0
                        },
                        "annualBalanceQuarterDays": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "saveableQuarterDays": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 9007199254740991
                        },
                        "reason": {
                          "type": "string",
                          "nullable": true
                        }
                      },
                      "required": [
                        "kind",
                        "quarterDays",
                        "annualBalanceQuarterDays",
                        "saveableQuarterDays",
                        "reason"
                      ]
                    }
                  ]
                },
                "submittedAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                },
                "attention": {
                  "type": "object",
                  "properties": {
                    "level": {
                      "type": "string",
                      "enum": [
                        "clean",
                        "attention"
                      ]
                    },
                    "reasons": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "level",
                    "reasons"
                  ]
                },
                "bulkEligible": {
                  "type": "boolean"
                },
                "notices": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "type": "string"
                      },
                      "dates": {
                        "default": [],
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        }
                      }
                    },
                    "required": [
                      "code"
                    ]
                  }
                },
                "entity": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "work_week"
                          ]
                        },
                        "membershipId": {
                          "type": "string"
                        },
                        "mondayIso": {
                          "type": "string",
                          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                        },
                        "workDayIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "kind",
                        "membershipId",
                        "mondayIso",
                        "workDayIds"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "expense"
                          ]
                        },
                        "expenseId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "expenseId"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "trip"
                          ]
                        },
                        "tripId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "tripId"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "leave"
                          ]
                        },
                        "periodId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "periodId"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "swap"
                          ]
                        },
                        "swapId": {
                          "type": "string"
                        },
                        "planningUnitId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "swapId",
                        "planningUnitId"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "training"
                          ]
                        },
                        "requestId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "requestId"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "open_shift_claim"
                          ]
                        },
                        "openShiftId": {
                          "type": "string"
                        },
                        "membershipId": {
                          "type": "string"
                        },
                        "planningUnitId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "openShiftId",
                        "membershipId",
                        "planningUnitId"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "leave_save"
                          ]
                        },
                        "proposalId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "proposalId"
                      ]
                    }
                  ]
                },
                "can": {
                  "type": "object",
                  "properties": {
                    "approve": {
                      "type": "boolean"
                    },
                    "return": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "approve",
                    "return"
                  ]
                },
                "lockToken": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "id",
                "kind",
                "subject",
                "display",
                "submittedAt",
                "attention",
                "bulkEligible",
                "entity",
                "can",
                "lockToken"
              ]
            }
          },
          "pageInfo": {
            "type": "object",
            "properties": {
              "nextCursor": {
                "type": "string",
                "nullable": true
              },
              "hasMore": {
                "type": "boolean"
              }
            },
            "required": [
              "nextCursor",
              "hasMore"
            ]
          },
          "counts": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "byKind": {
                "type": "object",
                "properties": {
                  "work_week": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "expense": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "trip": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "leave": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "swap": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "training": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "open_shift_claim": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "leave_save": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "work_week",
                  "expense",
                  "trip",
                  "leave",
                  "swap",
                  "training",
                  "open_shift_claim",
                  "leave_save"
                ]
              },
              "attention": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "bulkEligible": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "total",
              "byKind",
              "attention",
              "bulkEligible"
            ]
          },
          "truncated": {
            "type": "boolean"
          }
        },
        "required": [
          "items",
          "pageInfo",
          "counts",
          "truncated"
        ]
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem document. Branch on `code`, never on `title` or `detail`: `code` is a stable machine-readable identifier, the human-readable fields exist for logs and may change.",
        "required": [
          "type",
          "title",
          "status",
          "code"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Problem type URI. Points at the documentation anchor for `code` when the code is catalogued, otherwise `about:blank`.",
            "example": "https://kelomo.fi/developers/guides/error-codes/#code-read_only_key"
          },
          "title": {
            "type": "string",
            "description": "Short human-readable phrase for the status class."
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code, repeated in the body."
          },
          "detail": {
            "type": "string",
            "nullable": true,
            "description": "Human-readable specifics for this occurrence. Never a translated message."
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable error identifier — the field to branch on. Catalogued at /developers/guides/error-codes/.",
            "example": "read_only_key"
          },
          "requestId": {
            "type": "string",
            "description": "Identifier of this request, mirrored in the `X-Request-Id` response header. Quote it in support requests."
          }
        }
      }
    },
    "headers": {
      "RequestId": {
        "description": "Identifier of this request. Echoed from the caller’s `X-Request-Id` when it is a safe token, generated otherwise. Log it — it is the key support asks for.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimitLimit": {
        "description": "Requests allowed in the current one-minute window under the binding limit.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Requests left in the current window under the binding limit.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "Unix time (seconds) at which the current window resets.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitPolicy": {
        "description": "The limits in force, as `<limit>;w=<seconds>;scope=<key|tenant>` pairs — a 429 can come from either bucket.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed request: schema validation failed, a parameter value is out of range, or a required header is missing (`idempotency_key_required`).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, expired or revoked credentials — `invalid_token`, `api_key_expired`, `api_key_owner_inactive`.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Authenticated but not permitted: the key’s scope or the member’s capabilities do not cover the operation (`insufficient_role`), or the key is read-only (`read_only_key`).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such object in this organisation.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "FeatureNotInPlan": {
        "description": "The organisation’s plan does not include the module this operation belongs to (`feature_not_in_plan`, with the missing `feature` named in the body). Not a permission problem — an administrator activates the module in Kelomo.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflict with the object’s current state — an append-only boundary, a concurrent edit, or an idempotency-key collision (`idempotency_key_reused`, `idempotency_key_in_flight`).",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded for the key or for the organisation. Wait `Retry-After` seconds and retry.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "ServerError": {
        "description": "Unexpected server error. Retry idempotent operations; quote `requestId` if it persists.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "bearer": []
    }
  ],
  "externalDocs": {
    "description": "Kelomo developer portal — interactive reference, guides and changelog",
    "url": "https://kelomo.fi/developers/"
  }
}
