{"openapi": "3.1.0", "info": {"title": "Operations Hub API", "version": "0.1.1", "description": ""}, "paths": {"/api/graphql-schema": {"get": {"operationId": "builderapi_urls_graphql_schema", "summary": "GraphQL Schema (SDL)", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Return the pre-generated GraphQL schema in SDL format.", "tags": ["docs"]}}, "/api/auth": {"post": {"operationId": "aeroauth_api_authenticate", "summary": "Authenticate", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Authenticate the user.", "tags": ["auth"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Authenticate"}}}, "required": true}}}, "/api/clients/login": {"post": {"operationId": "aeroauth_api_client_login", "summary": "Client Login", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientLoginResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Authenticate by checking provided password against ALL decrypted project passwords.", "tags": ["auth"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientLoginRequest"}}}, "required": true}}}, "/api/logout": {"post": {"operationId": "aeroauth_api_do_logout", "summary": "Do Logout", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Logout the user (JWT or PWT).", "tags": ["auth"]}}, "/api/me": {"get": {"operationId": "aeroauth_api_get_user", "summary": "Get User", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/User"}}}}}, "description": "Get the user details.", "tags": ["auth"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/manufacturers": {"get": {"operationId": "list_manufacturers", "summary": "List Manufacturers", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "has_models", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter manufacturers that have at least one turbine or component model", "title": "Has Models"}, "required": false, "description": "Filter manufacturers that have at least one turbine or component model"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ManufacturerResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.manufacturers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_manufacturer", "summary": "Create Manufacturer", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ManufacturerResponse"}}}}}, "description": "Create a new item.", "tags": ["core.manufacturers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ManufacturerCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/manufacturers/{id}": {"get": {"operationId": "get_manufacturer", "summary": "Get Manufacturer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ManufacturerResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.manufacturers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_manufacturer", "summary": "Update Manufacturer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ManufacturerResponse"}}}}}, "description": "Update an item.", "tags": ["core.manufacturers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ManufacturerUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_manufacturer", "summary": "Delete Manufacturer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.manufacturers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/component-models": {"get": {"operationId": "list_component_models", "summary": "List Component Models", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "manufacturer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "required": false, "description": "Filter by manufacturer ID"}, {"in": "query", "name": "component_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component type ID", "title": "Component Type Id"}, "required": false, "description": "Filter by component type ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ComponentModelResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.component-models"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_component_model", "summary": "Create Component Model", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ComponentModelResponse"}}}}}, "description": "Create a new item.", "tags": ["core.component-models"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ComponentModelCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/component-models/{id}": {"get": {"operationId": "get_component_model", "summary": "Get Component Model", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ComponentModelResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.component-models"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_component_model", "summary": "Update Component Model", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ComponentModelResponse"}}}}}, "description": "Update an item.", "tags": ["core.component-models"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ComponentModelUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_component_model", "summary": "Delete Component Model", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.component-models"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-models": {"get": {"operationId": "list_turbine_models", "summary": "List Turbine Models", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "manufacturer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "required": false, "description": "Filter by manufacturer ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TurbineModelResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.turbine-models"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_turbine_model", "summary": "Create Turbine Model", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineModelResponse"}}}}}, "description": "Create a new item.", "tags": ["core.turbine-models"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineModelCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-models/{id}": {"get": {"operationId": "get_turbine_model", "summary": "Get Turbine Model", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineModelResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.turbine-models"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_turbine_model", "summary": "Update Turbine Model", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineModelResponse"}}}}}, "description": "Update an item.", "tags": ["core.turbine-models"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineModelUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_turbine_model", "summary": "Delete Turbine Model", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.turbine-models"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/component-types": {"get": {"operationId": "list_componenttypes", "summary": "List ComponentTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ComponentTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.component-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/robot-sets": {"get": {"operationId": "core_endpoints_robot_sets_list_robot_sets", "summary": "List Robot Sets", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "services", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service IDs (comma-separated, e.g., '1,2,3')", "title": "Services"}, "required": false, "description": "Filter by service IDs (comma-separated, e.g., '1,2,3')"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RobotSetResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all robot sets with optional search, sorting, and filtering by services.", "tags": ["core.robot-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_robot_sets_create_robot_set", "summary": "Create Robot Set", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetResponse"}}}}}, "description": "Create a new robot set with optional services.", "tags": ["core.robot-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/robot-sets/{id}": {"get": {"operationId": "core_endpoints_robot_sets_get_robot_set", "summary": "Get Robot Set", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetResponse"}}}}}, "description": "Get a single robot set by ID.", "tags": ["core.robot-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "core_endpoints_robot_sets_update_robot_set", "summary": "Update Robot Set", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetResponse"}}}}}, "description": "Update a robot set with optional services.", "tags": ["core.robot-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_robot_sets_delete_robot_set", "summary": "Delete Robot Set", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a robot set.", "tags": ["core.robot-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/robot-sets/{id}/netsuite-sync": {"post": {"operationId": "core_endpoints_robot_sets_sync_robot_set_to_netsuite", "summary": "Sync this robot set to NetSuite \u2014 creates if missing, patches name if already linked", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetResponse"}}}}}, "description": "Push a robot set to NetSuite.\n\n- No netsuite_id: creates the record in NS and saves the returned ID.\n- Has netsuite_id: patches the name in NS to match Ops Hub.", "tags": ["core.robot-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/robot-sets/{robot_set_id}/services": {"get": {"operationId": "list_robot_set_services", "summary": "List Services for Robot Set", "parameters": [{"in": "path", "name": "robot_set_id", "schema": {"title": "Robot Set Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RobotSetServicesResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.robot-sets.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources/summary": {"get": {"operationId": "get_resource_summary", "summary": "Get Resource Summary", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceSummary"}}}}}, "description": "Get a summary of resources (total count, technicians, teams).", "tags": ["core.resources"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources/{resource_id}/service-positions": {"get": {"operationId": "list_resource_service_positions", "summary": "List Service Positions for Resource", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ResourceServicePositionResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.resources.service-positions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_resource_service_position", "summary": "Create Service Position", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceServicePositionResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.resources.service-positions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceServicePositionCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources/{resource_id}/service-positions/{position_id}": {"get": {"operationId": "get_resource_service_position", "summary": "Get Service Position", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "position_id", "schema": {"title": "Position Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceServicePositionResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.resources.service-positions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_resource_service_position", "summary": "Update Service Position", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "position_id", "schema": {"title": "Position Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceServicePositionResponse"}}}}}, "description": "Update a child item.", "tags": ["core.resources.service-positions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceServicePositionUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_resource_service_position", "summary": "Delete Service Position", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "position_id", "schema": {"title": "Position Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.resources.service-positions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources/{resource_id}/certificates": {"get": {"operationId": "list_resource_certificates", "summary": "List Certificates for Resource", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ResourceCertificateResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.resources.certificates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_resource_certificate", "summary": "Create Certificate", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceCertificateResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.resources.certificates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceCertificateCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources/{resource_id}/certificates/{certificate_id}": {"get": {"operationId": "get_resource_certificate", "summary": "Get Certificate", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "certificate_id", "schema": {"title": "Certificate Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceCertificateResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.resources.certificates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_resource_certificate", "summary": "Update Certificate", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "certificate_id", "schema": {"title": "Certificate Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceCertificateResponse"}}}}}, "description": "Update a child item.", "tags": ["core.resources.certificates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceCertificateUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_resource_certificate", "summary": "Delete Certificate", "parameters": [{"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "certificate_id", "schema": {"title": "Certificate Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.resources.certificates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources": {"get": {"operationId": "list_resources", "summary": "List Resources", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by full_name, user name or email (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by full_name, user name or email (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "resource_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by resource type", "title": "Resource Type"}, "required": false, "description": "Filter by resource type"}, {"in": "query", "name": "user_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by linked user ID", "title": "User Id"}, "required": false, "description": "Filter by linked user ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ResourceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.resources"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_resource", "summary": "Create Resource", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceResponse"}}}}}, "description": "Create a new item.", "tags": ["core.resources"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resources/{id}": {"get": {"operationId": "get_resource", "summary": "Get Resource", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.resources"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_resource", "summary": "Update Resource", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceResponse"}}}}}, "description": "Update an item.", "tags": ["core.resources"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_resource", "summary": "Delete Resource", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.resources"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resource-sets": {"get": {"operationId": "list_resource_sets", "summary": "List Resource Sets", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ResourceSetResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_resource_set", "summary": "Create Resource Set", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceSetResponse"}}}}}, "description": "Create a new item.", "tags": ["core.resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceSetCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/resource-sets/{id}": {"get": {"operationId": "get_resource_set", "summary": "Get Resource Set", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceSetResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_resource_set", "summary": "Update Resource Set", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceSetResponse"}}}}}, "description": "Update an item.", "tags": ["core.resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResourceSetUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_resource_set", "summary": "Delete Resource Set", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/countries": {"get": {"operationId": "list_countrys", "summary": "List Countrys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CountryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.countries"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/locations/resolve-coordinates": {"post": {"operationId": "resolve_location_coordinates", "summary": "Resolve geographic data from coordinates", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveCoordinatesResponse"}}}}}, "description": "Resolve address, timezone, country, city, and state from coordinates.", "tags": ["core.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveCoordinatesRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/locations": {"get": {"operationId": "list_locations", "summary": "List Locations", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Filter by location type"}, "required": false, "description": "Filter by location type"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "required": false, "description": "Filter by country ID"}, {"in": "query", "name": "timezone_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by timezone ID", "title": "Timezone Id"}, "required": false, "description": "Filter by timezone ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/LocationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_location", "summary": "Create Location", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LocationResponse"}}}}}, "description": "Create a new item.", "tags": ["core.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/LocationCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/locations/{id}": {"get": {"operationId": "get_location", "summary": "Get Location", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LocationResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_location", "summary": "Update Location", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LocationResponse"}}}}}, "description": "Update an item.", "tags": ["core.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/LocationUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_location", "summary": "Delete Location", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/services/{service_id}/pricing-units": {"get": {"operationId": "list_service_pricing_units", "summary": "List Pricing Units for Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServicePricingUnitResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.services.pricing-units"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/services/{service_id}/related-services": {"get": {"operationId": "list_service_related_services", "summary": "List Related Services for Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceRelatedServiceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.services.related-services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/services": {"get": {"operationId": "core_endpoints_services_v2_list_services", "summary": "List Services", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by code (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "categories", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by category IDs (comma-separated, e.g., '1,2,3')", "title": "Categories"}, "required": false, "description": "Filter by category IDs (comma-separated, e.g., '1,2,3')"}, {"in": "query", "name": "is_service", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether this is a service (true/false)", "title": "Is Service"}, "required": false, "description": "Filter by whether this is a service (true/false)"}, {"in": "query", "name": "service_family_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by capability family ID", "title": "Service Family Id"}, "required": false, "description": "Filter by capability family ID"}, {"in": "query", "name": "deprecated", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by deprecation state (true/false). Omit to return both; pass false to list only the services that can still be sold.", "title": "Deprecated"}, "required": false, "description": "Filter by deprecation state (true/false). Omit to return both; pass false to list only the services that can still be sold."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all services with optional search, sorting, and filtering by categories.", "tags": ["core.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/services/{service_id}": {"get": {"operationId": "core_endpoints_services_v2_get_service", "summary": "Get Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve a single service by its ID.", "tags": ["core.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/service-categories": {"get": {"operationId": "list_service_categorys", "summary": "List Service Categorys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceCategoryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.service-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/service-families": {"get": {"operationId": "list_service_familys", "summary": "List Service Familys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code or name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by code or name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by exact family code", "title": "Code"}, "required": false, "description": "Filter by exact family code"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceFamilyResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.service-families"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/service-groups": {"get": {"operationId": "list_service_groups", "summary": "List Service Groups", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceGroupResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.service-groups"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/pricing-units": {"get": {"operationId": "list_pricingunits", "summary": "List PricingUnits", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PricingUnitResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.pricing-units"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/erp-parts": {"get": {"operationId": "list_erp_parts", "summary": "List ERP Parts", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "category_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "required": false}, {"in": "query", "name": "erp_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Erp Status"}, "required": false}, {"in": "query", "name": "part_code_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Part Code Id"}, "required": false}, {"in": "query", "name": "flagged", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Flagged"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ErpPartResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List synced Monitor ERP parts with search, filters, and pagination.", "tags": ["core.erp-parts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/erp-parts/{id}": {"get": {"operationId": "get_erp_part", "summary": "Get ERP Part", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErpPartResponse"}}}}}, "description": "Get a single ERP part by ID.", "tags": ["core.erp-parts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_erp_part", "summary": "Set ERP Part category", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErpPartResponse"}}}}}, "description": "Flag an ERP part with an item category (or clear it with null).", "tags": ["core.erp-parts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErpPartUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/erp-part-codes": {"get": {"operationId": "list_erp_part_codes", "summary": "List ERP Part Codes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ErpPartCodeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.erp-part-codes"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/item-categories": {"get": {"operationId": "list_item_categorys", "summary": "List Item Categorys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ItemCategoryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.item-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/service-standard-items": {"get": {"operationId": "list_service_standard_items", "summary": "List Service Standard Items", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Region"}, "required": false}, {"in": "query", "name": "part_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Part Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceStandardItemResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.service-standard-items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_service_standard_item", "summary": "Create Service Standard Item", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceStandardItemResponse"}}}}}, "description": "Create a new item.", "tags": ["core.service-standard-items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceStandardItemCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/service-standard-items/{id}": {"get": {"operationId": "get_service_standard_item", "summary": "Get Service Standard Item", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceStandardItemResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.service-standard-items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_service_standard_item", "summary": "Update Service Standard Item", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceStandardItemResponse"}}}}}, "description": "Update an item.", "tags": ["core.service-standard-items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceStandardItemUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_service_standard_item", "summary": "Delete Service Standard Item", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.service-standard-items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-requirements": {"get": {"operationId": "list_certificate_requirement_rules", "summary": "List Certificate Requirement Rules", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "certificate_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Certificate Id"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "service_family_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Family Id"}, "required": false}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Region"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateRequirementRuleResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.certificate-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_certificate_requirement_rule", "summary": "Create Certificate Requirement Rule", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateRequirementRuleResponse"}}}}}, "description": "Create a new item.", "tags": ["core.certificate-requirements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateRequirementRuleCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-requirements/{id}": {"get": {"operationId": "get_certificate_requirement_rule", "summary": "Get Certificate Requirement Rule", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateRequirementRuleResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.certificate-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_certificate_requirement_rule", "summary": "Update Certificate Requirement Rule", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateRequirementRuleResponse"}}}}}, "description": "Update an item.", "tags": ["core.certificate-requirements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateRequirementRuleUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_certificate_requirement_rule", "summary": "Delete Certificate Requirement Rule", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.certificate-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-requirement-groups": {"post": {"operationId": "save_certificate_requirement_group", "summary": "Save a certificate mapping group", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateRequirementRuleResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Create/patch/delete a whole mapping group in one transaction.", "tags": ["core.certificate-requirements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateRequirementGroupSave"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/recompute-suggested-certificates": {"post": {"operationId": "recompute_project_suggested_certificates", "summary": "Recompute suggested certificates for a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Refresh the materialized per-site suggestions for one project.\n\nDerived data only, so any internal user may trigger it \u2014 the same\nrecompute the dimension-change signals run.", "tags": ["core.certificate-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/relationship-types": {"get": {"operationId": "list_relationshiptypes", "summary": "List RelationshipTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RelationshipTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.relationship-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/standards": {"get": {"operationId": "list_standards", "summary": "List Standards", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name", "title": "Search"}, "required": false, "description": "Search by name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field", "title": "Sort"}, "required": false, "description": "Sort by field"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by type", "title": "Type"}, "required": false, "description": "Filter by type"}, {"in": "query", "name": "key", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by key", "title": "Key"}, "required": false, "description": "Filter by key"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/StandardResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.standards"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/positions": {"get": {"operationId": "list_positions", "summary": "List Positions", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "is_lead", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by lead flag", "title": "Is Lead"}, "required": false, "description": "Filter by lead flag"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PositionResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.positions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_position", "summary": "Create Position", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PositionResponse"}}}}}, "description": "Create a new item.", "tags": ["core.positions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PositionCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/positions/{id}": {"get": {"operationId": "get_position", "summary": "Get Position", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PositionResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.positions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_position", "summary": "Update Position", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PositionResponse"}}}}}, "description": "Update an item.", "tags": ["core.positions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PositionUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_position", "summary": "Delete Position", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.positions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/users": {"get": {"operationId": "core_endpoints_users_list_users", "summary": "List Users", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by first name, last name, or email (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by first name, last name, or email (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by first_name, last_name, or email (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by first_name, last_name, or email (prefix with - for descending)"}, {"in": "query", "name": "roles", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by role names (comma-separated)", "title": "Roles"}, "required": false, "description": "Filter by role names (comma-separated)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/UserResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List active users.", "tags": ["core.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_user", "summary": "Create User", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserResponse"}}}}}, "description": "Create a new user.", "tags": ["core.users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/users/{id}": {"get": {"operationId": "get_user", "summary": "Get User", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserResponse"}}}}}, "description": "Get a single user by ID.", "tags": ["core.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_user", "summary": "Update User", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserResponse"}}}}}, "description": "Update an existing user.", "tags": ["core.users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_user", "summary": "Delete User", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a user (set is_active=False).", "tags": ["core.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/users/{id}/reset-password": {"post": {"operationId": "reset_user_password", "summary": "Reset User Password", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Send a one-time password-reset link to the user's email.", "tags": ["core.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/roles": {"get": {"operationId": "core_endpoints_roles_get_roles", "summary": "Get Roles", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/IDWithName"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return all available roles.", "tags": ["core.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers": {"get": {"operationId": "list_customers", "summary": "List Customers", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by display_name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by display_name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "required": false, "description": "Filter by country ID"}, {"in": "query", "name": "currency_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by currency ID", "title": "Currency Id"}, "required": false, "description": "Filter by currency ID"}, {"in": "query", "name": "type", "schema": {"allOf": [{"description": "Which customer types a list returns.\n\nEvery :class:`CustomerType` plus ``ALL``. Kept separate from\n:class:`CustomerType` because ``ALL`` is a question a caller can ask, never a\nvalue a customer row can hold.\n\n``COMMERCIAL`` is the default on every list, so a customer that cannot be\nbilled never reaches a picker asking \"which commercial party is this\". ``ALL``\nis for the surfaces that administer the ``parent_customer`` hierarchy rather\nthan choose a payer.", "enum": ["COMMERCIAL", "VIRTUAL", "ALL"], "title": "CustomerTypeFilter", "type": "string"}], "default": "COMMERCIAL", "description": "Which customer types to return. Defaults to COMMERCIAL, so no picker offers a customer that cannot be billed. ALL returns every type, for the surfaces that administer the parent-customer hierarchy rather than choose a payer."}, "required": false, "description": "Which customer types to return. Defaults to COMMERCIAL, so no picker offers a customer that cannot be billed. ALL returns every type, for the surfaces that administer the parent-customer hierarchy rather than choose a payer."}, {"in": "query", "name": "parent_customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent customer ID", "title": "Parent Customer Id"}, "required": false, "description": "Filter by parent customer ID"}, {"in": "query", "name": "pipedrive_org_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by Pipedrive organization ID", "title": "Pipedrive Org Id"}, "required": false, "description": "Filter by Pipedrive organization ID"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter to customers linked to this Location via the core.customer_locations junction (active rows only).", "title": "Location Id"}, "required": false, "description": "Filter to customers linked to this Location via the core.customer_locations junction (active rows only)."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all customers with optional search, sorting, and filtering.", "tags": ["core.customers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer", "summary": "Create Customer", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerResponse"}}}}}, "description": "Create a new customer, mirroring it to NetSuite when a subsidiary is chosen.\n\nThe NetSuite mirroring rules live in ``CustomerManager.create`` \u2014 when a\nsubsidiary is picked the customer is filed under that billing entity or the\nwhole save fails; when none is supplied the customer is created locally\n(legacy behaviour).", "tags": ["core.customers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{id}": {"get": {"operationId": "get_customer", "summary": "Get Customer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerResponse"}}}}}, "description": "Get a single customer by ID.", "tags": ["core.customers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer", "summary": "Update Customer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerResponse"}}}}}, "description": "Update a customer.", "tags": ["core.customers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer", "summary": "Delete Customer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a customer.", "tags": ["core.customers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{id}/netsuite-subsidiary": {"get": {"operationId": "get_customer_netsuite_subsidiary", "summary": "Get Customer NetSuite Subsidiary", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerNetsuiteSubsidiary"}}}}}, "description": "Return the customer's current subsidiary, read live from NetSuite.", "tags": ["core.customers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/vendors": {"get": {"operationId": "list_vendors", "summary": "List Vendors", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by display_name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by display_name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "required": false, "description": "Filter by country ID"}, {"in": "query", "name": "currency_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by currency ID", "title": "Currency Id"}, "required": false, "description": "Filter by currency ID"}, {"in": "query", "name": "parent_vendor_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent vendor ID", "title": "Parent Vendor Id"}, "required": false, "description": "Filter by parent vendor ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VendorResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_vendor", "summary": "Create Vendor", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VendorResponse"}}}}}, "description": "Create a new item.", "tags": ["core.vendors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VendorCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/vendors/{id}": {"get": {"operationId": "get_vendor", "summary": "Get Vendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VendorResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_vendor", "summary": "Update Vendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VendorResponse"}}}}}, "description": "Update an item.", "tags": ["core.vendors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VendorUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_vendor", "summary": "Delete Vendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/contacts": {"get": {"operationId": "list_customer_contacts", "summary": "List Contacts for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerContactResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.contacts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_contact", "summary": "Create Contact", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerContactResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.contacts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerContactCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/contacts/{contact_id}": {"get": {"operationId": "get_customer_contact", "summary": "Get Contact", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "contact_id", "schema": {"title": "Contact Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerContactResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.contacts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_contact", "summary": "Update Contact", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "contact_id", "schema": {"title": "Contact Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerContactResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.contacts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerContactUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_contact", "summary": "Delete Contact", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "contact_id", "schema": {"title": "Contact Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.contacts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/addresses": {"get": {"operationId": "list_customer_addresss", "summary": "List Addresses for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerAddressResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.addresses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_address", "summary": "Create Address", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAddressResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.addresses"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAddressCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/addresses/{address_id}": {"get": {"operationId": "get_customer_address", "summary": "Get Address", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "address_id", "schema": {"title": "Address Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAddressResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.addresses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_address", "summary": "Update Address", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "address_id", "schema": {"title": "Address Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAddressResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.addresses"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAddressUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_address", "summary": "Delete Address", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "address_id", "schema": {"title": "Address Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.addresses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/bank-accounts": {"get": {"operationId": "list_customer_bank_accounts", "summary": "List Bank Accounts for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerBankAccountResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.bank-accounts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_bank_account", "summary": "Create Bank Account", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerBankAccountResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.bank-accounts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerBankAccountCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/bank-accounts/{bank_account_id}": {"get": {"operationId": "get_customer_bank_account", "summary": "Get Bank Account", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "bank_account_id", "schema": {"title": "Bank Account Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerBankAccountResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.bank-accounts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_bank_account", "summary": "Update Bank Account", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "bank_account_id", "schema": {"title": "Bank Account Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerBankAccountResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.bank-accounts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerBankAccountUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_bank_account", "summary": "Delete Bank Account", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "bank_account_id", "schema": {"title": "Bank Account Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.bank-accounts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/locations": {"get": {"operationId": "list_customer_locations", "summary": "List Locations for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "relationship_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by relationship type ID", "title": "Relationship Id"}, "required": false, "description": "Filter by relationship type ID"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Filter by location type"}, "required": false, "description": "Filter by location type"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerLocationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_location", "summary": "Create Location", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerLocationResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerLocationCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/locations/{customer_location_id}": {"get": {"operationId": "get_customer_location", "summary": "Get Location", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "customer_location_id", "schema": {"title": "Customer Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerLocationResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_location", "summary": "Update Location", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "customer_location_id", "schema": {"title": "Customer Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerLocationResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerLocationUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_location", "summary": "Delete Location", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "customer_location_id", "schema": {"title": "Customer Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customer-locations": {"get": {"operationId": "list_customer_locations", "summary": "List Customer Locations", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "required": false, "description": "Filter by customer ID"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "relationship_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by relationship type ID", "title": "Relationship Id"}, "required": false, "description": "Filter by relationship type ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerLocationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.customer-locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/users": {"get": {"operationId": "list_customer_users", "summary": "List Users for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerUserResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_user", "summary": "Create User", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerUserResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerUserCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/users/{user_id}": {"get": {"operationId": "get_customer_user", "summary": "Get User", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "user_id", "schema": {"title": "User Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerUserResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_user", "summary": "Update User", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "user_id", "schema": {"title": "User Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerUserResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerUserUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_user", "summary": "Delete User", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "user_id", "schema": {"title": "User Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/roles": {"get": {"operationId": "list_customer_roles", "summary": "List Roles for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerRoleResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.roles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/turbines": {"get": {"operationId": "list_customer_turbines", "summary": "List Turbines for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "relationship_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by relationship type ID", "title": "Relationship Id"}, "required": false, "description": "Filter by relationship type ID"}, {"in": "query", "name": "is_virtual", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by virtual turbine", "title": "Is Virtual"}, "required": false, "description": "Filter by virtual turbine"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine location ID", "title": "Location Id"}, "required": false, "description": "Filter by turbine location ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerTurbineResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_turbine", "summary": "Create Turbine", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerTurbineResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.turbines"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerTurbineCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/turbines/{customer_turbine_id}": {"get": {"operationId": "get_customer_turbine", "summary": "Get Turbine", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "customer_turbine_id", "schema": {"title": "Customer Turbine Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerTurbineResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_turbine", "summary": "Update Turbine", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "customer_turbine_id", "schema": {"title": "Customer Turbine Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerTurbineResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.turbines"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerTurbineUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_turbine", "summary": "Delete Turbine", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "customer_turbine_id", "schema": {"title": "Customer Turbine Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/delay-categories": {"get": {"operationId": "list_delaycategorys", "summary": "List DelayCategorys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by code (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "enabled", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}, "required": false, "description": "Filter by enabled status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DelayCategoryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.delay-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_delaycategory", "summary": "Create DelayCategory", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayCategoryResponse"}}}}}, "description": "Create a new item.", "tags": ["core.delay-categories"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayCategoryCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/delay-categories/{id}": {"get": {"operationId": "get_delaycategory", "summary": "Get DelayCategory", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayCategoryResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.delay-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_delaycategory", "summary": "Update DelayCategory", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayCategoryResponse"}}}}}, "description": "Update an item.", "tags": ["core.delay-categories"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayCategoryUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_delaycategory", "summary": "Delete DelayCategory", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.delay-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/delay-types": {"get": {"operationId": "list_delaytypes", "summary": "List DelayTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by code (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "delay_category_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by delay category ID", "title": "Delay Category Id"}, "required": false, "description": "Filter by delay category ID"}, {"in": "query", "name": "enabled", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}, "required": false, "description": "Filter by enabled status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DelayTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.delay-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_delaytype", "summary": "Create DelayType", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayTypeResponse"}}}}}, "description": "Create a new item.", "tags": ["core.delay-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayTypeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/delay-types/{id}": {"get": {"operationId": "get_delaytype", "summary": "Get DelayType", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayTypeResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.delay-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_delaytype", "summary": "Update DelayType", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayTypeResponse"}}}}}, "description": "Update an item.", "tags": ["core.delay-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayTypeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_delaytype", "summary": "Delete DelayType", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.delay-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/delays": {"get": {"operationId": "list_delays", "summary": "List Delays", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by comment (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by comment (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "delay_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by delay type ID", "title": "Delay Type Id"}, "required": false, "description": "Filter by delay type ID"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "robot_set_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by robot set ID", "title": "Robot Set Id"}, "required": false, "description": "Filter by robot set ID"}, {"in": "query", "name": "resource_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource ID", "title": "Resource Id"}, "required": false, "description": "Filter by resource ID"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order ID", "title": "Service Order Id"}, "required": false, "description": "Filter by service order ID"}, {"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder ID", "title": "Workorder Id"}, "required": false, "description": "Filter by workorder ID"}, {"in": "query", "name": "workorder_activity_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder activity ID", "title": "Workorder Activity Id"}, "required": false, "description": "Filter by workorder activity ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DelayResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.delays"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_delay", "summary": "Create Delay", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayResponse"}}}}}, "description": "Create a new item.", "tags": ["core.delays"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/delays/{id}": {"get": {"operationId": "get_delay", "summary": "Get Delay", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.delays"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_delay", "summary": "Update Delay", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayResponse"}}}}}, "description": "Update an item.", "tags": ["core.delays"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DelayUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_delay", "summary": "Delete Delay", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.delays"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/notifications": {"get": {"operationId": "core_endpoints_notifications_list_notifications", "summary": "List Notifications", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "is_read", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Read"}, "required": false}, {"in": "query", "name": "is_archived", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Archived"}, "required": false}, {"in": "query", "name": "category", "schema": {"anyOf": [{"$ref": "#/components/schemas/NotificationCategory"}, {"type": "null"}]}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NotificationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List notifications for the current user.", "tags": ["core.notifications"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/notifications/unread-count": {"get": {"operationId": "core_endpoints_notifications_unread_count", "summary": "Unread Count", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationUnreadCountResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get unread notification count for the current user.", "tags": ["core.notifications"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/notifications/mark-all-read": {"patch": {"operationId": "core_endpoints_notifications_mark_all_read", "summary": "Mark All Read", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationMarkAllReadResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Mark all unread notifications as read for the current user.", "tags": ["core.notifications"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/notifications/seen": {"patch": {"operationId": "core_endpoints_notifications_mark_seen", "summary": "Mark Seen", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationSeenResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Mark the given notifications as seen \u2014 not read, so the badge is unaffected.", "tags": ["core.notifications"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationSeenRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/notifications/preferences": {"get": {"operationId": "core_endpoints_notifications_list_preferences", "summary": "List Preferences", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NotificationPreferenceItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List channel preferences for every category for the current user.", "tags": ["core.notifications"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "core_endpoints_notifications_upsert_preferences", "summary": "Upsert Preferences", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NotificationPreferenceItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Upsert channel preferences, returning the full set afterwards.", "tags": ["core.notifications"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NotificationPreferenceItem"}, "title": "Payload", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/notifications/{notification_id}": {"get": {"operationId": "core_endpoints_notifications_get_notification", "summary": "Get Notification", "parameters": [{"in": "path", "name": "notification_id", "schema": {"title": "Notification Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a single notification for the current user.", "tags": ["core.notifications"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "core_endpoints_notifications_update_notification", "summary": "Update Notification", "parameters": [{"in": "path", "name": "notification_id", "schema": {"title": "Notification Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update notification read/archived status.", "tags": ["core.notifications"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/NotificationUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/notifications/v1/events": {"post": {"operationId": "announce_notification_event", "summary": "Announce Event", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EventResult"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Announce one event from the menu, saying whether it produced an entry.\n\n``announced`` is False when the event was already announced, or when it had\nnobody to tag. Both are ordinary outcomes for a caller that retries or that\nreports a milestone whose role has no members yet, so neither is an error.", "tags": ["notifications.events"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EventRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/file-entity-links": {"get": {"operationId": "list_file_entity_links", "summary": "List File Entity Links", "parameters": [{"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "file_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by file ID", "title": "File Id"}, "required": false, "description": "Filter by file ID"}, {"in": "query", "name": "workorder_activity_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder activity ID", "title": "Workorder Activity Id"}, "required": false, "description": "Filter by workorder activity ID"}, {"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder ID", "title": "Workorder Id"}, "required": false, "description": "Filter by workorder ID"}, {"in": "query", "name": "service_order_line_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order line ID", "title": "Service Order Line Id"}, "required": false, "description": "Filter by service order line ID"}, {"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order ID", "title": "Service Order Id"}, "required": false, "description": "Filter by service order ID"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "turbine_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine component ID", "title": "Turbine Component Id"}, "required": false, "description": "Filter by turbine component ID"}, {"in": "query", "name": "anomaly_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly ID", "title": "Anomaly Id"}, "required": false, "description": "Filter by anomaly ID"}, {"in": "query", "name": "service_result_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service result ID", "title": "Service Result Id"}, "required": false, "description": "Filter by service result ID"}, {"in": "query", "name": "customer_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer location ID", "title": "Customer Location Id"}, "required": false, "description": "Filter by customer location ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileEntityLinkResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.file-entity-links"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_file_entity_link", "summary": "Create File Entity Link", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileEntityLinkResponse"}}}}}, "description": "Create a new item.", "tags": ["core.file-entity-links"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileEntityLinkCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/file-entity-links/{id}": {"get": {"operationId": "get_file_entity_link", "summary": "Get File Entity Link", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileEntityLinkResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.file-entity-links"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_file_entity_link", "summary": "Update File Entity Link", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileEntityLinkResponse"}}}}}, "description": "Update an item.", "tags": ["core.file-entity-links"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileEntityLinkUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_file_entity_link", "summary": "Delete File Entity Link", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.file-entity-links"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbines/import-template": {"get": {"operationId": "download_turbine_import_template", "summary": "Download turbine import CSV template", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Return an empty CSV file with all import column headers.", "tags": ["core.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbines/import": {"post": {"operationId": "import_turbines_csv", "summary": "Import turbines from CSV", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineImportResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Parse a CSV file, validate all rows, and create turbines atomically.", "tags": ["core.turbines"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbines": {"get": {"operationId": "list_turbines", "summary": "List Turbines", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "manufacturer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "required": false, "description": "Filter by manufacturer ID"}, {"in": "query", "name": "manufacturer_turbine_model_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine model ID", "title": "Manufacturer Turbine Model Id"}, "required": false, "description": "Filter by turbine model ID"}, {"in": "query", "name": "is_virtual", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by virtual turbine", "title": "Is Virtual"}, "required": false, "description": "Filter by virtual turbine"}, {"in": "query", "name": "health", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated health levels (0=NO_DATA, 100=HEALTHY, 20=ATTENTION_NEEDED, 30=ACTION_REQUIRED)", "title": "Health"}, "required": false, "description": "Comma-separated health levels (0=NO_DATA, 100=HEALTHY, 20=ATTENTION_NEEDED, 30=ACTION_REQUIRED)"}, {"in": "query", "name": "ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated turbine IDs \u2014 returns only turbines whose id is in the list (batch fetch by id)", "title": "Ids"}, "required": false, "description": "Comma-separated turbine IDs \u2014 returns only turbines whose id is in the list (batch fetch by id)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TurbineResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_turbine", "summary": "Create Turbine", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineResponse"}}}}}, "description": "Create a new item.", "tags": ["core.turbines"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbines/{id}": {"get": {"operationId": "get_turbine", "summary": "Get Turbine", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_turbine", "summary": "Update Turbine", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineResponse"}}}}}, "description": "Update an item.", "tags": ["core.turbines"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_turbine", "summary": "Delete Turbine", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-components/import-template": {"get": {"operationId": "download_component_import_template", "summary": "Download turbine component import CSV template", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Return an empty CSV file with all import column headers.", "tags": ["core.turbine-components"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-components/import": {"post": {"operationId": "import_turbine_components_csv", "summary": "Import turbine components from CSV", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ComponentImportResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Parse a CSV file, validate all rows, and create components atomically.", "tags": ["core.turbine-components"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-components/{id}/reassignment-history": {"get": {"operationId": "list_turbine_component_reassignment_history", "summary": "List Turbine Component Reassignment History", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TurbineComponentReassignmentHistoryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return paginated reassignment history for a blade component, newest first.", "tags": ["core.turbine-components"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-components": {"get": {"operationId": "list_turbine_components", "summary": "List Turbine Components", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by serial number (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by serial number (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "component_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component type ID", "title": "Component Type Id"}, "required": false, "description": "Filter by component type ID"}, {"in": "query", "name": "manufacturer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "required": false, "description": "Filter by manufacturer ID"}, {"in": "query", "name": "model_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component model ID", "title": "Model Id"}, "required": false, "description": "Filter by component model ID"}, {"in": "query", "name": "parent_turbine_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent turbine component ID", "title": "Parent Turbine Component Id"}, "required": false, "description": "Filter by parent turbine component ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TurbineComponentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.turbine-components"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_turbine_component", "summary": "Create Turbine Component", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineComponentResponse"}}}}}, "description": "Create a new item.", "tags": ["core.turbine-components"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineComponentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-components/{id}": {"get": {"operationId": "get_turbine_component", "summary": "Get Turbine Component", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineComponentResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.turbine-components"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_turbine_component", "summary": "Update Turbine Component", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineComponentResponse"}}}}}, "description": "Update an item.", "tags": ["core.turbine-components"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineComponentUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_turbine_component", "summary": "Delete Turbine Component", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.turbine-components"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificates": {"get": {"operationId": "list_certificates", "summary": "List Certificates", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "category_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by category", "title": "Category Id"}, "required": false, "description": "Filter by category"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country", "title": "Country Id"}, "required": false, "description": "Filter by country"}, {"in": "query", "name": "is_active", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active flag", "title": "Is Active"}, "required": false, "description": "Filter by active flag"}, {"in": "query", "name": "source", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by origin system", "title": "Source"}, "required": false, "description": "Filter by origin system"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.certificates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_certificate", "summary": "Create Certificate", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateResponse"}}}}}, "description": "Create a new item.", "tags": ["core.certificates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificates/{id}": {"get": {"operationId": "get_certificate", "summary": "Get Certificate", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.certificates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_certificate", "summary": "Update Certificate", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateResponse"}}}}}, "description": "Update an item.", "tags": ["core.certificates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_certificate", "summary": "Delete Certificate", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.certificates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-categories": {"get": {"operationId": "list_certificatecategorys", "summary": "List CertificateCategorys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateCategoryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.certificate-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_certificatecategory", "summary": "Create CertificateCategory", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateCategoryResponse"}}}}}, "description": "Create a new item.", "tags": ["core.certificate-categories"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateCategoryCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-categories/{id}": {"get": {"operationId": "get_certificatecategory", "summary": "Get CertificateCategory", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateCategoryResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.certificate-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_certificatecategory", "summary": "Update CertificateCategory", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateCategoryResponse"}}}}}, "description": "Update an item.", "tags": ["core.certificate-categories"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateCategoryUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_certificatecategory", "summary": "Delete CertificateCategory", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.certificate-categories"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-issuers": {"get": {"operationId": "list_certificateissuers", "summary": "List CertificateIssuers", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country", "title": "Country Id"}, "required": false, "description": "Filter by country"}, {"in": "query", "name": "is_active", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active flag", "title": "Is Active"}, "required": false, "description": "Filter by active flag"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateIssuerResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.certificate-issuers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_certificateissuer", "summary": "Create CertificateIssuer", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateIssuerResponse"}}}}}, "description": "Create a new item.", "tags": ["core.certificate-issuers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateIssuerCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-issuers/{id}": {"get": {"operationId": "get_certificateissuer", "summary": "Get CertificateIssuer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateIssuerResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.certificate-issuers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_certificateissuer", "summary": "Update CertificateIssuer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateIssuerResponse"}}}}}, "description": "Update an item.", "tags": ["core.certificate-issuers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateIssuerUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_certificateissuer", "summary": "Delete CertificateIssuer", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.certificate-issuers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-offerings": {"get": {"operationId": "list_certificateofferings", "summary": "List CertificateOfferings", "parameters": [{"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "certificate_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by certificate", "title": "Certificate Id"}, "required": false, "description": "Filter by certificate"}, {"in": "query", "name": "issuer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by issuer", "title": "Issuer Id"}, "required": false, "description": "Filter by issuer"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country", "title": "Country Id"}, "required": false, "description": "Filter by country"}, {"in": "query", "name": "is_active", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active flag", "title": "Is Active"}, "required": false, "description": "Filter by active flag"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateOfferingResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.certificate-offerings"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_certificateoffering", "summary": "Create CertificateOffering", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateOfferingResponse"}}}}}, "description": "Create a new item.", "tags": ["core.certificate-offerings"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateOfferingCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-offerings/{id}": {"get": {"operationId": "get_certificateoffering", "summary": "Get CertificateOffering", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateOfferingResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.certificate-offerings"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_certificateoffering", "summary": "Update CertificateOffering", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateOfferingResponse"}}}}}, "description": "Update an item.", "tags": ["core.certificate-offerings"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateOfferingUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_certificateoffering", "summary": "Delete CertificateOffering", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.certificate-offerings"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-expenses": {"get": {"operationId": "list_certificateexpenses", "summary": "List CertificateExpenses", "parameters": [{"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "resource_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource", "title": "Resource Id"}, "required": false, "description": "Filter by resource"}, {"in": "query", "name": "certificate_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by certificate", "title": "Certificate Id"}, "required": false, "description": "Filter by certificate"}, {"in": "query", "name": "resource_certificate_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by linked issuance row", "title": "Resource Certificate Id"}, "required": false, "description": "Filter by linked issuance row"}, {"in": "query", "name": "issuer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by issuer", "title": "Issuer Id"}, "required": false, "description": "Filter by issuer"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project", "title": "Project Id"}, "required": false, "description": "Filter by project"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"$ref": "#/components/schemas/CertificateExpenseStatus"}, {"type": "null"}], "description": "Filter by status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CertificateExpenseResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.certificate-expenses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_certificateexpense", "summary": "Create CertificateExpense", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateExpenseResponse"}}}}}, "description": "Create a new item.", "tags": ["core.certificate-expenses"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateExpenseCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/certificate-expenses/{id}": {"get": {"operationId": "get_certificateexpense", "summary": "Get CertificateExpense", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateExpenseResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.certificate-expenses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_certificateexpense", "summary": "Update CertificateExpense", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateExpenseResponse"}}}}}, "description": "Update an item.", "tags": ["core.certificate-expenses"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertificateExpenseUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_certificateexpense", "summary": "Delete CertificateExpense", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.certificate-expenses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-components": {"get": {"operationId": "list_anomalycomponents", "summary": "List AnomalyComponents", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "required": false, "description": "Search in name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "inspection_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by inspection type", "title": "Inspection Type"}, "required": false, "description": "Filter by inspection type"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyComponentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-types": {"get": {"operationId": "list_anomaly_types", "summary": "List AnomalyTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "required": false, "description": "Search in name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "inspection_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by inspection type", "title": "Inspection Type"}, "required": false, "description": "Filter by inspection type"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code context. Omit for general/cross-service views (all types returned). When a non-LER- code is supplied, LER QC deviation types are excluded. When a LER- code is supplied, all types are returned.", "title": "Service Code"}, "required": false, "description": "Service code context. Omit for general/cross-service views (all types returned). When a non-LER- code is supplied, LER QC deviation types are excluded. When a LER- code is supplied, all types are returned."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List anomaly types, filtered by service code context.\n\nNo ``service_code`` \u2192 all types returned (general / cross-service view).\n``service_code`` starts with ``LER-`` \u2192 all types returned.\n``service_code`` present but not ``LER-`` \u2192 LER QC deviation types excluded.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-root-cause-types": {"get": {"operationId": "list_anomalyrootcausetypes", "summary": "List AnomalyRootCauseTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in title", "title": "Search"}, "required": false, "description": "Search in title"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyRootCauseTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-parent-types": {"get": {"operationId": "list_anomalyparenttypes", "summary": "List AnomalyParentTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "required": false, "description": "Search in name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyParentTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-materials": {"get": {"operationId": "list_anomalymaterials", "summary": "List AnomalyMaterials", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "required": false, "description": "Search in name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "anomaly_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly type ID", "title": "Anomaly Type Id"}, "required": false, "description": "Filter by anomaly type ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyMaterialResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-component-type-maps": {"get": {"operationId": "list_anomalycomponenttypemaps", "summary": "List AnomalyComponentTypeMaps", "parameters": [{"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "anomaly_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly component ID", "title": "Anomaly Component Id"}, "required": false, "description": "Filter by anomaly component ID"}, {"in": "query", "name": "anomaly_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly type ID", "title": "Anomaly Type Id"}, "required": false, "description": "Filter by anomaly type ID"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code context. Omit for general/cross-service views (all mappings returned). When a non-LER- code is supplied, mappings to LER QC deviation types are excluded. When a LER- code is supplied, all mappings are returned.", "title": "Service Code"}, "required": false, "description": "Service code context. Omit for general/cross-service views (all mappings returned). When a non-LER- code is supplied, mappings to LER QC deviation types are excluded. When a LER- code is supplied, all mappings are returned."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyComponentTypeMapResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List anomaly component-type mappings, filtered by service code context.\n\nNo ``service_code`` -> all mappings returned (used by unscoped filter views).\n``service_code`` starts with ``LER-`` -> all mappings returned.\n``service_code`` present but not ``LER-`` -> mappings to LER QC deviation types\nexcluded (used by the component-driven cascade when creating an anomaly).", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-recommendations": {"get": {"operationId": "list_anomalyrecommendations", "summary": "List AnomalyRecommendations", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "required": false, "description": "Search in name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by type", "title": "Type"}, "required": false, "description": "Filter by type"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyRecommendationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_anomalyrecommendation", "summary": "Create AnomalyRecommendation", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyRecommendationResponse"}}}}}, "description": "Create a new item.", "tags": ["core.anomalies"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyRecommendationCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-recommendations/{id}": {"get": {"operationId": "get_anomalyrecommendation", "summary": "Get AnomalyRecommendation", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyRecommendationResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_anomalyrecommendation", "summary": "Update AnomalyRecommendation", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyRecommendationResponse"}}}}}, "description": "Update an item.", "tags": ["core.anomalies"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyRecommendationUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_anomalyrecommendation", "summary": "Delete AnomalyRecommendation", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/anomaly-client-fields": {"get": {"operationId": "list_customer_anomaly_client_fields", "summary": "List Anomaly Client Fields for Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "required": false, "description": "Search in name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by field type", "title": "Type"}, "required": false, "description": "Filter by field type"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyClientFieldResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.customers.anomaly-client-fields"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customer_anomaly_client_field", "summary": "Create Anomaly Client Field", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyClientFieldResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.customers.anomaly-client-fields"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyClientFieldCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/customers/{customer_id}/anomaly-client-fields/{field_id}": {"get": {"operationId": "get_customer_anomaly_client_field", "summary": "Get Anomaly Client Field", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "field_id", "schema": {"title": "Field Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyClientFieldResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.customers.anomaly-client-fields"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customer_anomaly_client_field", "summary": "Update Anomaly Client Field", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "field_id", "schema": {"title": "Field Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyClientFieldResponse"}}}}}, "description": "Update a child item.", "tags": ["core.customers.anomaly-client-fields"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyClientFieldUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customer_anomaly_client_field", "summary": "Delete Anomaly Client Field", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "field_id", "schema": {"title": "Field Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.customers.anomaly-client-fields"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomaly-client-fields/applicable": {"get": {"operationId": "list_applicable_anomaly_client_fields", "summary": "List Applicable Anomaly Client Fields", "parameters": [{"in": "query", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyClientFieldResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Client fields an anomaly on this service order line may record.\n\nResolves the line's customer and turbine model, then keeps only the fields\nthe caller is allowed to see under each field's ``access_rules``. An empty\nlist means the form shows no custom fields. Shares the manager helper with\n``anomalyClientFieldsForServiceOrderLine``, so REST and GraphQL offer the\nsame set.", "tags": ["core.customers.anomaly-client-fields"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomalies/{id}/files/": {"get": {"operationId": "core_endpoints_anomalies_files_get_anomaly_files", "summary": "Fetch all files associated with a given anomaly ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by file type", "title": "Type"}, "required": false, "description": "Filter by file type"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Fetch all files associated with a given anomaly ID.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_anomalies_files_post_anomaly_file", "summary": "Upload a new file associated with a given anomaly ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Accepts multipart/form-data with one or more files. Each file should be sent as a separate part with the key 'file'.", "tags": ["core.anomalies"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"items": {"format": "binary", "type": "string"}, "title": "File", "type": "array"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomalies/{id}/files/{file_id}/": {"get": {"operationId": "core_endpoints_anomalies_files_get_anomaly_file", "summary": "Fetch a specific file associated with a given anomaly ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_id", "schema": {"title": "File Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileResponse"}}}}}, "description": "Returns the file if it is associated with the given anomaly.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_anomalies_files_delete_anomaly_file", "summary": "Delete a file associated with a given anomaly ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_id", "schema": {"title": "File Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Deletes the specified file if it is associated with the given anomaly.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomalies/{id}/files/b64/": {"post": {"operationId": "core_endpoints_anomalies_files_post_anomaly_body_file", "summary": "Upload a new body file associated with a given anomaly ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Accepts a JSON object `{\"files\": [...], \"additional_information\": {...}}`. Each file includes base64-encoded data; `additional_information` is optional JSON metadata stored on each file link. A legacy bare array `[...]` is still accepted (no metadata).", "tags": ["core.anomalies"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/BodyFileWrapper"}, {"items": {"$ref": "#/components/schemas/BodyFile"}, "type": "array"}], "title": "Payload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/files/{entity_type}/{entity_id}/": {"get": {"operationId": "core_endpoints_files_get_entity_files", "summary": "Fetch all files associated with a supported entity.", "parameters": [{"in": "path", "name": "entity_type", "schema": {"title": "Entity Type", "type": "string"}, "required": true}, {"in": "path", "name": "entity_id", "schema": {"title": "Entity Id", "type": "integer"}, "required": true}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by file type", "title": "Type"}, "required": false, "description": "Filter by file type"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Fetch all files associated with a supported entity.", "tags": ["core.files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_files_post_entity_file", "summary": "Upload one or more files for a supported entity.", "parameters": [{"in": "path", "name": "entity_type", "schema": {"title": "Entity Type", "type": "string"}, "required": true}, {"in": "path", "name": "entity_id", "schema": {"title": "Entity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Upload one or more files for a supported entity.", "tags": ["core.files"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"items": {"format": "binary", "type": "string"}, "title": "File", "type": "array"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/files/{entity_type}/{entity_id}/{file_id}/": {"get": {"operationId": "core_endpoints_files_get_entity_file", "summary": "Fetch a specific file associated with a supported entity.", "parameters": [{"in": "path", "name": "entity_type", "schema": {"title": "Entity Type", "type": "string"}, "required": true}, {"in": "path", "name": "entity_id", "schema": {"title": "Entity Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_id", "schema": {"title": "File Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileResponse"}}}}}, "description": "Fetch a specific file associated with a supported entity.", "tags": ["core.files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_files_delete_entity_file", "summary": "Delete a file associated with a supported entity.", "parameters": [{"in": "path", "name": "entity_type", "schema": {"title": "Entity Type", "type": "string"}, "required": true}, {"in": "path", "name": "entity_id", "schema": {"title": "Entity Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_id", "schema": {"title": "File Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Delete a file associated with a supported entity.", "tags": ["core.files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/files/{entity_type}/{entity_id}/{file_id}/download/": {"get": {"operationId": "core_endpoints_files_download_entity_file", "summary": "Resolve and download an entity file.", "parameters": [{"in": "path", "name": "entity_type", "schema": {"title": "Entity Type", "type": "string"}, "required": true}, {"in": "path", "name": "entity_id", "schema": {"title": "Entity Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_id", "schema": {"title": "File Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Resolve and serve an entity file. Use ?variant=preview for thumbnail if available.", "tags": ["core.files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/files": {"post": {"operationId": "core_endpoints_files_post_bare_file", "summary": "Upload one or more files without binding them to an entity.", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Bare upload \u2014 returns `core.File` records with integer ids that callers reference from subsequent entity-create payloads (e.g. `evidence_file_ids` on ProjectScopeChangeRequest create). The creating endpoint is responsible for writing the corresponding `FileEntityLink` rows in its own transaction.", "tags": ["core.files"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"items": {"format": "binary", "type": "string"}, "title": "File", "type": "array"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/files/b64/": {"post": {"operationId": "core_endpoints_files_post_bare_body_file", "summary": "Upload base64-encoded files without binding them to an entity.", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Base64 counterpart of the bare upload endpoint.\n\nIntentionally kept on the legacy flat-array body \u2014 bare uploads carry no\nentity link and therefore no ``additional_information`` metadata.", "tags": ["core.files"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BodyFile"}, "title": "Files", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/files/{entity_type}/{entity_id}/b64/": {"post": {"operationId": "core_endpoints_files_post_entity_body_file", "summary": "Upload base64-encoded files for a supported entity.", "parameters": [{"in": "path", "name": "entity_type", "schema": {"title": "Entity Type", "type": "string"}, "required": true}, {"in": "path", "name": "entity_id", "schema": {"title": "Entity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Accepts a JSON object `{\"files\": [...], \"additional_information\": {...}}` where `additional_information` is optional JSON metadata stored on each created file link. A legacy bare array `[...]` is still accepted for backward compatibility (no metadata).", "tags": ["core.files"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/BodyFileWrapper"}, {"items": {"$ref": "#/components/schemas/BodyFile"}, "type": "array"}], "title": "Payload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomalies": {"get": {"operationId": "list_anomalies", "summary": "List anomalies", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text search", "title": "Search"}, "required": false, "description": "Free-text search"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "turbine_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine component ID", "title": "Turbine Component Id"}, "required": false, "description": "Filter by turbine component ID"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by work order ID", "title": "Workorder Id"}, "required": false, "description": "Filter by work order ID"}, {"in": "query", "name": "service_order_line_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order line ID", "title": "Service Order Line Id"}, "required": false, "description": "Filter by service order line ID"}, {"in": "query", "name": "anomaly_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly type ID", "title": "Anomaly Type Id"}, "required": false, "description": "Filter by anomaly type ID"}, {"in": "query", "name": "anomaly_sub_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly sub-type ID", "title": "Anomaly Sub Type Id"}, "required": false, "description": "Filter by anomaly sub-type ID"}, {"in": "query", "name": "anomaly_major_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by major component ID", "title": "Anomaly Major Component Id"}, "required": false, "description": "Filter by major component ID"}, {"in": "query", "name": "anomaly_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component ID", "title": "Anomaly Component Id"}, "required": false, "description": "Filter by component ID"}, {"in": "query", "name": "anomaly_sub_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sub-component ID", "title": "Anomaly Sub Component Id"}, "required": false, "description": "Filter by sub-component ID"}, {"in": "query", "name": "anomaly_material_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by material ID", "title": "Anomaly Material Id"}, "required": false, "description": "Filter by material ID"}, {"in": "query", "name": "parent_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent type ID", "title": "Parent Type Id"}, "required": false, "description": "Filter by parent type ID"}, {"in": "query", "name": "root_cause_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by root cause ID", "title": "Root Cause Id"}, "required": false, "description": "Filter by root cause ID"}, {"in": "query", "name": "parent_anomaly_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "deprecated": true, "description": "Deprecated: No longer used. Filter by link_group instead.", "title": "Parent Anomaly Id"}, "required": false, "description": "Deprecated: No longer used. Filter by link_group instead.", "deprecated": true}, {"in": "query", "name": "severity", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by severity", "title": "Severity"}, "required": false, "description": "Filter by severity"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "client_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client status", "title": "Client Status"}, "required": false, "description": "Filter by client status"}, {"in": "query", "name": "stage", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by stage", "title": "Stage"}, "required": false, "description": "Filter by stage"}, {"in": "query", "name": "internal_external", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by internal/external", "title": "Internal External"}, "required": false, "description": "Filter by internal/external"}, {"in": "query", "name": "side", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by side", "title": "Side"}, "required": false, "description": "Filter by side"}, {"in": "query", "name": "rib", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by rib", "title": "Rib"}, "required": false, "description": "Filter by rib"}, {"in": "query", "name": "cross_section_side", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by cross section side", "title": "Cross Section Side"}, "required": false, "description": "Filter by cross section side"}, {"in": "query", "name": "cross_section_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by cross section type", "title": "Cross Section Type"}, "required": false, "description": "Filter by cross section type"}, {"in": "query", "name": "registered_by", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by registered by", "title": "Registered By"}, "required": false, "description": "Filter by registered by"}, {"in": "query", "name": "registration_origin", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by registration origin", "title": "Registration Origin"}, "required": false, "description": "Filter by registration origin"}, {"in": "query", "name": "created_at_gte", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by creation date >= (YYYY-MM-DD)", "title": "Created At Gte"}, "required": false, "description": "Filter by creation date >= (YYYY-MM-DD)"}, {"in": "query", "name": "created_at_lte", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by creation date <= (YYYY-MM-DD)", "title": "Created At Lte"}, "required": false, "description": "Filter by creation date <= (YYYY-MM-DD)"}, {"in": "query", "name": "updated_at_gte", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by last modified date >= (YYYY-MM-DD)", "title": "Updated At Gte"}, "required": false, "description": "Filter by last modified date >= (YYYY-MM-DD)"}, {"in": "query", "name": "updated_at_lte", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by last modified date <= (YYYY-MM-DD)", "title": "Updated At Lte"}, "required": false, "description": "Filter by last modified date <= (YYYY-MM-DD)"}, {"in": "query", "name": "custom_value_filters", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client custom field values. A JSON array of {\"custom_field_id\": int, \"values\": [str, ...]}; criteria are AND-ed across fields and values are OR-ed within a field. Requires service_order_line_id, whose customer + turbine model gate which fields may be filtered on (a hidden field is rejected).", "title": "Custom Value Filters"}, "required": false, "description": "Filter by client custom field values. A JSON array of {\"custom_field_id\": int, \"values\": [str, ...]}; criteria are AND-ed across fields and values are OR-ed within a field. Requires service_order_line_id, whose customer + turbine model gate which fields may be filtered on (a hidden field is rejected)."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AnomalyResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List anomalies with optional filtering and pagination.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_anomaly", "summary": "Create anomaly", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyResponse"}}}}}, "description": "Create a new anomaly.", "tags": ["core.anomalies"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomalies/{id}": {"get": {"operationId": "get_anomaly", "summary": "Get anomaly", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyResponse"}}}}}, "description": "Get a single anomaly by ID.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_anomaly", "summary": "Update anomaly", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyResponse"}}}}}, "description": "Partially update anomaly.", "tags": ["core.anomalies"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_anomaly", "summary": "Delete anomaly", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete anomaly.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/anomalies/{id}/main-image": {"get": {"operationId": "get_anomaly_main_image", "summary": "Get anomaly main image", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Resolve and redirect to anomaly main image URL.", "tags": ["core.anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/blade-diagrams": {"post": {"operationId": "generate_blade_diagram", "summary": "Generate blade anomaly diagram as PNG", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Generate a horizontal blade anomaly diagram from explicitly provided anomaly data and blade length. Returns a PNG image (580x119).", "tags": ["core.blade-diagrams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BladeDiagramRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/blade-diagrams/service-order-lines/{sol_id}": {"get": {"operationId": "generate_blade_diagram_by_sol", "summary": "Generate blade diagram from service order line", "parameters": [{"in": "path", "name": "sol_id", "schema": {"description": "Service order line ID", "title": "Sol Id", "type": "integer"}, "required": true, "description": "Service order line ID"}, {"in": "query", "name": "turbine_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter anomalies by turbine component ID", "title": "Turbine Component Id"}, "required": false, "description": "Filter anomalies by turbine component ID"}], "responses": {"200": {"description": "OK"}}, "description": "Generate a blade anomaly diagram by pulling anomalies and blade length from a service order line. Returns a PNG image (580x119).", "tags": ["core.blade-diagrams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/cross-sections": {"post": {"operationId": "generate_cross_section", "summary": "Generate blade cross-section as PNG", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Generate a blade cross-section schematic with a single anomaly marker from explicitly provided anomaly data. Returns a PNG image rendered from the shared cross-section component (visually identical to the in-app panel).\n\nThe diagram shows the blade airfoil profile with internal structural lines determined by `cross_section_type`. A coloured marker is placed at the position defined by `cross_section_side` and `cross_section_distance` / `cross_section_chamber_distance`.\n\nAt least one of `cross_section_distance` or `cross_section_chamber_distance` should be provided for marker placement.", "tags": ["core.cross-sections"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CrossSectionRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/cross-sections/anomalies/{anomaly_id}": {"get": {"operationId": "generate_cross_section_by_anomaly", "summary": "Generate cross-section from anomaly", "parameters": [{"in": "path", "name": "anomaly_id", "schema": {"description": "Anomaly ID", "title": "Anomaly Id", "type": "integer"}, "required": true, "description": "Anomaly ID"}], "responses": {"200": {"description": "OK"}}, "description": "Convenience endpoint that generates a blade cross-section schematic by reading cross-section fields directly from an existing anomaly record. Returns a PNG image rendered from the shared cross-section component.\n\nFields read from the anomaly: `cross_section_side`, `cross_section_distance`, `cross_section_chamber_distance`, `cross_section_type`, `severity`, `internal_external`, `side`, `rib`.", "tags": ["core.cross-sections"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/timezones": {"get": {"operationId": "list_timezones", "summary": "List Timezones", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by city (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by city (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TimezoneResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.timezones"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/currencies": {"get": {"operationId": "list_currencys", "summary": "List Currencys", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CurrencyResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.currencies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/business-regions": {"get": {"operationId": "list_business_regions", "summary": "List Business Regions", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BusinessRegionResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.business-regions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/regions": {"get": {"operationId": "list_regions", "summary": "List Regions", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RegionResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.regions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/terms-of-service": {"get": {"operationId": "list_terms_of_services", "summary": "List Terms of Services", "parameters": [{"in": "query", "name": "is_active", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active status", "title": "Is Active"}, "required": false, "description": "Filter by active status"}, {"in": "query", "name": "is_required", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by required status", "title": "Is Required"}, "required": false, "description": "Filter by required status"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by title, version, or content", "title": "Search"}, "required": false, "description": "Search by title, version, or content"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TermsOfServiceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["customer-portal"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/user-tos-acceptances": {"get": {"operationId": "list_user_tos_acceptances", "summary": "List User ToS Acceptances", "parameters": [{"in": "query", "name": "user_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by user ID", "title": "User Id"}, "required": false, "description": "Filter by user ID"}, {"in": "query", "name": "tos_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by ToS ID", "title": "Tos Id"}, "required": false, "description": "Filter by ToS ID"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/UserTosAcceptanceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List user ToS acceptances with optional filtering.\n\nQuery parameters:\n- user_id: Filter by user ID (optional)\n- tos_id: Filter by ToS ID (optional)\n- sort: Sort field (id, user_id, tos_id, created_at), prefix with '-' for descending\n- page: Page number (default: 1)\n- page_size: Items per page (default: 50)", "tags": ["customer-portal"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_user_tos_acceptance", "summary": "Create User ToS Acceptance", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserTosAcceptanceResponse"}}}}}, "description": "Create a new user ToS acceptance record.\n\nNote: This is an immutable record. Once created, it should never be updated.\nBoth user and created_by are set from the authenticated user.", "tags": ["customer-portal"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserTosAcceptanceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/daily": {"post": {"operationId": "customer_portal_download_daily_report", "summary": "Generate and download a daily report PDF", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Generate and download a daily report for a service order line.\n\nAccess is scoped to the authenticated user's customer projects.\nIf date is omitted, the report covers all activity dates for the SOL.\n\n``require_content=False`` \u2014 the deliberate opt-out from the empty-day refusal\nthe internal surfaces take. ``date`` may be omitted here, so \"empty\" means\n\"this line has no activity at all\", not \"nothing happened that day\"; the\ncaller is a portal in another repository whose 4xx handling we cannot see;\nand there is no dialog here to show a message in. A customer asking for a\nquiet line gets the quiet PDF rather than an error.", "tags": ["reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyReportDownloadRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/final": {"post": {"operationId": "customer_portal_download_final_report", "summary": "Download a final (SOL) report \u2014 engine-rendered or uploaded", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Download the final report for a service order line, whatever its type.\n\nThe single final-report entry point for the portal \u2014 callers do not need to\nknow how a given service's report is produced. Services outside\n``_UPLOADED_FINAL_REPORT_PREFIXES`` are rendered by the engine on demand; the\nrest have no engine template, so the document ops uploaded is streamed from\nstorage the way ``core.endpoints.files`` serves stored files (GCS blob bytes\nwith the blob's own content type, falling back to a public-URL redirect).\nEither way the response is the file bytes with a download\n``Content-Disposition``, so the client handles one shape. A response is not\nnecessarily a PDF: an uploaded LER report may be a DOCX/XLSX/ZIP, and its\n``Content-Type`` says so.\n\nThe customer-facing counterpart of the technician ``final-report/download``\nendpoint (AECP-303): access is scoped to the caller's customer purely by\nPostgreSQL RLS on ``ServiceOrderLine`` (via ``ServiceOrderHeader.customer_id``)\n\u2014 a SOL the caller cannot see is not found, and that gate stays ahead of\n*both* branches. LPS SOLs resolve the project's ``lps_standard_id`` for the\nengine; a missing template is a clear 4xx, as is an LER SOL whose report has\nnot been uploaded yet (404).", "tags": ["reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportDownloadRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/final/{service_order_line_id}/file": {"get": {"operationId": "customer_portal_download_final_report_file", "summary": "Download an uploaded final report file (e.g. LER)", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download the uploaded final report attached to a service order line.\n\nDeprecated in favour of ``POST /final``, which now serves uploaded finals\nitself, so no client needs to classify the report type. Kept \u2014 and marked\ndeprecated in the schema rather than described as such in prose \u2014 for clients\npinned to the two-endpoint contract; it delegates to the same resolution\nhelpers, so the two cannot drift.\n\nThe customer-safe uploaded-file path (TD-1 / AECP-267). Ownership is\n**verified, not assumed**: the SOL is resolved through the RLS-scoped\nqueryset first, so a SOL outside the caller's customer is invisible \u2192 404,\nand only then is its linked file served. This deliberately does **not** proxy\nthe generic ``/api/core/v1/files/service_order_line/{id}/`` endpoint, which\ncarries no customer RLS and no report permission.", "tags": ["reports"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/custom": {"post": {"operationId": "customer_portal_start_custom_report", "summary": "Request a custom report for a selection of turbines, locations or projects", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportStartResponse"}}}}}, "description": "Start rendering one document for the selection; returns a generation id to poll.\n\nThe selection is resolved and refused here, before the engine is called: an id\noutside the caller's customer, an unknown ``report_type``, band value or anomaly\ntype, an empty result and an oversized selection are each a 422 naming the cause.\nRequesting needs the Reports feature's Full level (``CUSTOMER_MANAGE_REPORTS``);\nfollowing the request needs View.", "tags": ["reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "customer_portal_list_custom_reports", "summary": "List the customer's latest custom report requests", "parameters": [{"in": "query", "name": "limit", "schema": {"default": 20, "description": "Newest requests to return", "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer"}, "required": false, "description": "Newest requests to return"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomReportSummary"}, "title": "Response", "type": "array"}}}}}, "description": "The caller's newest requests first, each with its family, status and the selection it was made for, so a finished document can be offered without a new render.", "tags": ["reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/custom/types": {"get": {"operationId": "customer_portal_custom_report_types", "summary": "List the report types a custom report can be requested for", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomReportType"}, "title": "Response", "type": "array"}}}}}, "description": "The registered families with the request fields each reads and its selection cap, so the portal form is driven by the server.", "tags": ["reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/custom/{generation_id}/status": {"get": {"operationId": "customer_portal_custom_report_status", "summary": "Poll a custom report request", "parameters": [{"in": "path", "name": "generation_id", "schema": {"title": "Generation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportStatusResponse"}}}}}, "description": "Poll a pending request once; it turns complete only after the PDF is stored in Ops Hub's own file store.", "tags": ["reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/reports/custom/{generation_id}/download": {"get": {"operationId": "customer_portal_download_custom_report", "summary": "Download a finished custom report", "parameters": [{"in": "path", "name": "generation_id", "schema": {"title": "Generation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Serve the stored PDF of a completed request under the name it was stored with; the engine is never called.", "tags": ["reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-question-configs": {"get": {"operationId": "list_project_question_configs", "summary": "List Project Question Configs", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by title", "title": "Search"}, "required": false, "description": "Search by title"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "section", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by section", "title": "Section"}, "required": false, "description": "Filter by section"}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}, "required": false, "description": "Filter by service ID"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code (e.g. IIN-ONS)", "title": "Service Code"}, "required": false, "description": "Filter by service code (e.g. IIN-ONS)"}, {"in": "query", "name": "enabled", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}, "required": false, "description": "Filter by enabled status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectQuestionConfigResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.project-question-configs"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-statuses": {"get": {"operationId": "list_project_statuss", "summary": "List Project Status", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by code (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "enabled", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}, "required": false, "description": "Filter by enabled status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectStatusResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.project-status"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/report-types": {"get": {"operationId": "list_report_types", "summary": "List Report Types", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "enabled", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Enabled"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ReportTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["core.report-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/pipedrive-deals": {"get": {"operationId": "list_pipedrive_deals", "summary": "List Pipedrive Deals", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by title (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by title (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PipedriveDealResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all Pipedrive deals with optional search and sorting.\n\nReturns deals with parsed titles (project code only).\nDeals without valid project codes are filtered out.", "tags": ["core.pipedrive-deals"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job-answers/bulk": {"patch": {"operationId": "bulk_update_project_pre_job_answers", "summary": "Bulk update Pre-Job Answers", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectPreJobAnswerResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update multiple pre-job answers for a project in a single request.", "tags": ["core.projects.pre-job-answers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobAnswerBulkUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job-answers": {"get": {"operationId": "list_project_pre-job_answers", "summary": "List Pre-Job Answers for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectPreJobAnswerResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.pre-job-answers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_pre-job_answer", "summary": "Create Pre-Job Answer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobAnswerResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.pre-job-answers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobAnswerCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job-answers/{answer_id}": {"get": {"operationId": "get_project_pre-job_answer", "summary": "Get Pre-Job Answer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "answer_id", "schema": {"title": "Answer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobAnswerResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.pre-job-answers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_pre-job_answer", "summary": "Update Pre-Job Answer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "answer_id", "schema": {"title": "Answer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobAnswerResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.pre-job-answers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobAnswerUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_pre-job_answer", "summary": "Delete Pre-Job Answer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "answer_id", "schema": {"title": "Answer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.pre-job-answers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/rfi-billing": {"get": {"operationId": "get_project_rfi_billing", "summary": "Get RFI Billing composite (ProjectBilling and linked purchase orders)", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RfiBillingCompositeResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.projects.rfi-billing"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_rfi_billing", "summary": "Update RFI Billing composite", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RfiBillingCompositeResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.projects.rfi-billing"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RfiBillingCompositeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job/sites": {"get": {"operationId": "get_pre_job_sites", "summary": "Get pre-job sites for a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreJobSitesResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return project locations enriched with pre-job answers, O&M address,\ncontacts, and file links.", "tags": ["core.projects.pre-job-sites"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/contacts": {"get": {"operationId": "list_project_contacts", "summary": "List Contacts for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectContactResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.contacts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_contact", "summary": "Create Contact", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectContactResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.contacts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectContactCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/contacts/{contact_id}": {"get": {"operationId": "get_project_contact", "summary": "Get Contact", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "contact_id", "schema": {"title": "Contact Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectContactResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.contacts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_contact", "summary": "Update Contact", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "contact_id", "schema": {"title": "Contact Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectContactResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.contacts"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectContactUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_contact", "summary": "Delete Contact", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "contact_id", "schema": {"title": "Contact Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.contacts"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/locations": {"get": {"operationId": "list_project_locations", "summary": "List Project Locations", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectLocationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all locations for a project.", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_locations", "summary": "Bulk Assign Locations to Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectLocationResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Bulk assign locations to project with legacy system sync.\n\nCreates records in:\n- core.project_location (new system)\n- projects.Site (legacy system)\n- projects_project_sites (legacy junction)\n\nAll within a single atomic transaction.", "tags": ["core.projects.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectLocationBulkCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/locations/service-coverage": {"get": {"operationId": "list_project_location_service_coverage", "summary": "Per project location, the service ids offered or scoped there", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectLocationServicesResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Service coverage per site: the union of approved-offer + scope services\nat each of the project's locations. Not paginated \u2014 bounded by site count.\nDefined before the ``/{location_id}`` routes so ``service-coverage`` isn't\nswallowed as a location id.", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/locations/{location_id}/pre-job": {"get": {"operationId": "get_project_location_pre_job", "summary": "Get pre-job composite for a project location", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "location_id", "schema": {"title": "Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreJobSiteCompositeResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Pre-job payload for one site.\n\n``location_id`` is ``ProjectLocation.id`` (not ``Location.id``).", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "update_project_location_pre_job", "summary": "Update pre-job composite for a project location", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "location_id", "schema": {"title": "Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreJobSiteCompositeResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Partial update for pre-job sections on one site.\n\n``location_id`` is ``ProjectLocation.id`` (not ``Location.id``).", "tags": ["core.projects.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PreJobSiteCompositeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job/prefill-source-projects": {"get": {"operationId": "list_pre_job_prefill_source_projects", "summary": "List candidate source projects for pre-job prefill", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "target_project_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Target Project Location Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PreJobPrefillSourceProject"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return every other active project as a prefill source candidate.\n\nWhen ``target_project_location_id`` is supplied, projects sharing the target\nsite's ``core.Location`` are sorted to the top (affordance only \u2014 any project\nis allowed as a source) and enriched with the shared site's services and\npre-job completion percentage. Standard ``Total-Count``/``Page``/``Page-Size``\nheaders; pass ``paginate=false`` to disable. Rows carry computed fields, so\nthe manager returns the pre-sliced ``items``/``total_count`` dict shape and\nthe pagination inputs are re-read here from the query string (the decorator\nconsumes them itself and slices only querysets).\n\nInternal users only \u2014 client portal (PWT) callers must not see cross-project\nprefill candidates.", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job/prefill-source-sites": {"get": {"operationId": "list_pre_job_prefill_source_sites", "summary": "List sites on a source project for the prefill picker", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PreJobPrefillSourceSite"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return the active sites on the requested source project.", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/locations/{location_id}": {"get": {"operationId": "get_project_location", "summary": "Get Project Location", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "location_id", "schema": {"title": "Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectLocationResponse"}}}}}, "description": "Get a specific project location.", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_location", "summary": "Update Project Location", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "location_id", "schema": {"title": "Location Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectLocationResponse"}}}}}, "description": "Update project location metadata (contact, additional_information).", "tags": ["core.projects.locations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectLocationUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_location", "summary": "Remove Location from Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "location_id", "schema": {"title": "Location Id", "type": "integer"}, "required": true}, {"in": "query", "name": "delete_pre_job_answers", "schema": {"default": false, "title": "Delete Pre Job Answers", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete project location and corresponding legacy Site.\n\n`delete_pre_job_answers=true` cascade soft-deletes the site's pre-job\nanswers (site-owned questionnaire data) instead of letting them block the\ndeletion. Used by the UI after warning the user. Other references (offer\nitems, resource sets, requests) still block.", "tags": ["core.projects.locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-components/{blade_id}/receptors": {"get": {"operationId": "list_blade_receptors", "summary": "List receptors on a single blade", "parameters": [{"in": "path", "name": "blade_id", "schema": {"title": "Blade Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-components.receptors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "sync_blade_receptors", "summary": "Sync receptors on a single blade", "parameters": [{"in": "path", "name": "blade_id", "schema": {"title": "Blade Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-components.receptors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorSyncBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbines/{turbine_id}/receptors": {"get": {"operationId": "list_turbine_receptors", "summary": "List receptors for all blades on a turbine (one round-trip)", "parameters": [{"in": "path", "name": "turbine_id", "schema": {"title": "Turbine Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineReceptorsResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbines.receptors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbines/{turbine_id}/receptors/init-from-preset": {"post": {"operationId": "init_turbine_receptors_from_preset", "summary": "Initialize receptors on every blade from the chosen preset", "parameters": [{"in": "path", "name": "turbine_id", "schema": {"title": "Turbine Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InitTurbineFromPresetResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Bulk-create receptor TurbineComponents on each blade from the chosen\npreset. Idempotent merge: only adds receptors whose name is missing on the\nblade. Returns a summary (created count, skipped existing, blade count,\ntemplate count) so the UI can render a meaningful toast.", "tags": ["core.turbines.receptors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/InitTurbineFromPresetBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/turbine-models/{turbine_model_id}/receptor-presets": {"get": {"operationId": "list_turbine_model_receptor_presets", "summary": "List receptor presets for a turbine model", "parameters": [{"in": "path", "name": "turbine_model_id", "schema": {"title": "Turbine Model Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorPresetListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-models.receptor-presets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_turbine_model_receptor_preset", "summary": "Create a receptor preset for a turbine model", "parameters": [{"in": "path", "name": "turbine_model_id", "schema": {"title": "Turbine Model Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorPresetResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-models.receptor-presets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorPresetCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/receptor-presets/{preset_id}": {"patch": {"operationId": "update_receptor_preset", "summary": "Update a receptor preset (name / description)", "parameters": [{"in": "path", "name": "preset_id", "schema": {"title": "Preset Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorPresetResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-models.receptor-presets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorPresetUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_receptor_preset", "summary": "Soft-delete a receptor preset (and its receptor children)", "parameters": [{"in": "path", "name": "preset_id", "schema": {"title": "Preset Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["core.turbine-models.receptor-presets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/receptor-presets/{preset_id}/receptors": {"get": {"operationId": "list_preset_receptors", "summary": "List receptors in a preset", "parameters": [{"in": "path", "name": "preset_id", "schema": {"title": "Preset Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-models.receptor-presets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "sync_preset_receptors", "summary": "Sync receptors in a preset", "parameters": [{"in": "path", "name": "preset_id", "schema": {"title": "Preset Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.turbine-models.receptor-presets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReceptorSyncBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/service-order-lines/{sol_id}/lps-results": {"get": {"operationId": "get_lps_results_context", "summary": "Per-blade LPS Service Results capture context", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LpsResultsContextResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.service-order-lines.lps-results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "upsert_lps_results", "summary": "Upsert per-receptor LPS measurements for a SOL", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LpsResultsUpsertResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.service-order-lines.lps-results"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/LpsResultsUpsertBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/current": {"get": {"operationId": "get_project_offer_current", "summary": "Get Current Offer for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Builder read route: the latest offer version for the project.\n\nReturns the single draft when one exists (a draft always carries the\nhighest version number), otherwise the latest submitted version. When the\nproject has no offers at all, Draft v1 is auto-created \u2014 parity with the\nlegacy ``GET /projects/{id}/offer`` first-open behaviour. The generic\noffers list stays read-only; only this route carries the side effect.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/draft": {"post": {"operationId": "create_project_offer_draft", "summary": "Create Draft Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Create a new draft offer version by copying the latest version's items.\n\nIdempotent: when a draft already exists it is returned unchanged. A new\ndraft gets ``version = latest + 1`` and copies line items with v1 lineage.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/{offer_id}/send-for-approval": {"post": {"operationId": "send_project_offer_for_approval", "summary": "Send Offer for Approval", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Send the draft offer for approval.\n\nThe required approver is routed from the deal value: offers of 100k and\nabove require CCO approval; below that, the regional sales manager by\nproject country (US/MX/CA -> USA, otherwise EU). Eligible approvers and\nthe sales owner are notified by email; notification failures never fail\nthe submission.", "tags": ["core.projects.offers"], "requestBody": {"content": {"application/json": {"schema": {"allOf": [{"$ref": "#/components/schemas/ProjectOfferSendForApprovalRequest"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/{offer_id}/approve": {"post": {"operationId": "approve_project_offer", "summary": "Approve Pending Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Approve the pending offer with a role-based authority check.\n\nCCO can approve any offer; regional sales managers only offers routed to\ntheir role (deals under 100k in their region). Approval cascades the core\nproject status to \"Planning\" and notifies the requestor and watchers.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/{offer_id}/reject": {"post": {"operationId": "reject_project_offer", "summary": "Reject Pending Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Reject the pending offer with a role-based authority check.\n\nThe rejection reason is stored in ``change_reason`` and included in the\nstatus notification sent to the requestor and watchers.", "tags": ["core.projects.offers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferRejectRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/history": {"get": {"operationId": "get_project_offer_history", "summary": "Get Offer History for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectOfferHistoryResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Offer version history: every non-draft version, newest first.\n\nRows carry the requestor/reviewer emails for display. The ``discount``\nfield is deprecated (stored value with undefined business meaning; never\napplied to totals) and is kept only for parity with the legacy history.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/download": {"post": {"operationId": "download_project_offer_pdf", "summary": "Download Offer PDF", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download the commercial offer as a PDF generated by the offerv2 pipeline.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/download-docx": {"post": {"operationId": "download_project_offer_docx", "summary": "Download Offer DOCX", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download the commercial offer as a DOCX generated by the offerv2 pipeline.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers": {"get": {"operationId": "list_project_offers", "summary": "List Offers for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by status", "title": "Search"}, "required": false, "description": "Search by status"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by offer status", "title": "Status"}, "required": false, "description": "Filter by offer status"}, {"in": "query", "name": "version", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by version number", "title": "Version"}, "required": false, "description": "Filter by version number"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectOfferResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_offer", "summary": "Create Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.offers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/{offer_id}": {"get": {"operationId": "get_project_offer", "summary": "Get Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_offer", "summary": "Update Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.offers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_offer", "summary": "Delete Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/billings": {"get": {"operationId": "list_project_billings", "summary": "List Billings for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectBillingResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.billings"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_billing", "summary": "Create Billing", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.billings"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/billings/{billing_id}": {"get": {"operationId": "get_project_billing", "summary": "Get Billing", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "billing_id", "schema": {"title": "Billing Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.billings"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_billing", "summary": "Update Billing", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "billing_id", "schema": {"title": "Billing Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.billings"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_billing", "summary": "Delete Billing", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "billing_id", "schema": {"title": "Billing Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.billings"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/report-types": {"get": {"operationId": "list_project_report_types", "summary": "List Report Types for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectReportTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.report-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_report_type", "summary": "Create Report Type", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectReportTypeResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.report-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectReportTypeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/report-types/{project_report_type_id}": {"get": {"operationId": "get_project_report_type", "summary": "Get Report Type", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "project_report_type_id", "schema": {"title": "Project Report Type Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectReportTypeResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.report-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_report_type", "summary": "Update Report Type", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "project_report_type_id", "schema": {"title": "Project Report Type Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectReportTypeResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.report-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectReportTypeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_report_type", "summary": "Delete Report Type", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "project_report_type_id", "schema": {"title": "Project Report Type Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.report-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/offers/{offer_id}/items": {"get": {"operationId": "list_offer_items", "summary": "List Items for Offer", "parameters": [{"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by description", "title": "Search"}, "required": false, "description": "Search by description"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}, "required": false, "description": "Filter by service ID"}, {"in": "query", "name": "is_service", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item's service is a service (vs addon/material)", "title": "Is Service"}, "required": false, "description": "Filter by whether item's service is a service (vs addon/material)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectOfferItemResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.offers.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_offer_item", "summary": "Create Item", "parameters": [{"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferItemResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.offers.items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferItemCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/offers/{offer_id}/items/{item_id}": {"get": {"operationId": "get_offer_item", "summary": "Get Item", "parameters": [{"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferItemResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.offers.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_offer_item", "summary": "Update Item", "parameters": [{"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferItemResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.offers.items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOfferItemUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_offer_item", "summary": "Delete Item", "parameters": [{"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.offers.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/offers/{offer_id}/items": {"get": {"operationId": "core_endpoints_project_offer_items_list_project_offer_items", "summary": "List Offer Items for Project Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "offer_id", "schema": {"title": "Offer Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by description", "title": "Search"}, "required": false, "description": "Search by description"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}, "required": false, "description": "Filter by service ID"}, {"in": "query", "name": "is_service", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item's service is a service (vs addon/material)", "title": "Is Service"}, "required": false, "description": "Filter by whether item's service is a service (vs addon/material)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectOfferItemResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List offer items for an offer, validating offer belongs to project.\n\nThis endpoint is project-scoped so it is safe for PWT (project password) sessions\nand avoids cross-project data exposure that would be possible with non-scoped\n/core/v1/offers/{offer_id}/items.", "tags": ["core.projects.offers.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/commercial-offers": {"get": {"operationId": "list_core_commercial_offers", "summary": "List Commercial Offers Pending Approval", "parameters": [{"in": "query", "name": "page", "schema": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 50, "maximum": 200, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false}, {"in": "query", "name": "include_approved", "schema": {"default": false, "title": "Include Approved", "type": "boolean"}, "required": false}, {"in": "query", "name": "required_approver_role", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Required Approver Role"}, "required": false}, {"in": "query", "name": "ordering", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "-offer_id", "title": "Ordering"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CommercialOfferInboxRow"}, "title": "Response", "type": "array"}}}}}, "description": "Return the paginated approvals inbox: latest non-draft offer per project.\n\nProjects whose latest offer version is a Draft are not listed. Approved\nrows are excluded unless ``include_approved`` is set. The ``discount``\nfield is deprecated (stored value with undefined business meaning; never\napplied to totals) and kept only for parity with the legacy inbox.", "tags": ["core.commercial-offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/commercial-offers/approve": {"post": {"operationId": "approve_core_commercial_offers", "summary": "Bulk Approve Commercial Offers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommercialOfferInboxBulkApproveResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Approve offers in bulk when the requester has the required authority.\n\nPer-offer authority is enforced (CCO approves anything; regional sales\nmanagers only offers routed to their role). Approved and Draft offers are\nskipped; Rejected offers CAN be approved (intended behaviour). Approval\ncascades the core project status to \"Planning\" and notifies requestors\nand watchers. No legacy ``projects.Project`` mirror is written.\n\nLocked projects (Completed/Cancelled) are guarded like every other Core\nworkflow mutation: a batch touching a locked project's offer is rejected\nbefore any transition \u2014 approving it would cascade the project back to\n\"Planning\".", "tags": ["core.commercial-offers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommercialOfferInboxBulkApproveRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/scope-items": {"get": {"operationId": "list_project_scope_items", "summary": "List Scope Items for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by location, turbine, service code/description, component type, or turbine component identifiers", "title": "Search"}, "required": false, "description": "Search by location, turbine, service code/description, component type, or turbine component identifiers"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}, "required": false, "description": "Filter by service ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectScopeItemResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.scope-items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_scope_item", "summary": "Create Scope Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeItemResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.scope-items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeItemCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/scope-items/{scope_item_id}": {"get": {"operationId": "get_project_scope_item", "summary": "Get Scope Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "scope_item_id", "schema": {"title": "Scope Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeItemResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.scope-items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_scope_item", "summary": "Update Scope Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "scope_item_id", "schema": {"title": "Scope Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeItemResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.scope-items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeItemUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_scope_item", "summary": "Delete Scope Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "scope_item_id", "schema": {"title": "Scope Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.scope-items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/scope-item-batches": {"post": {"operationId": "create_project_scope_item_batch", "summary": "Create Scope Item Batch", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectScopeItemResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Create multiple project scope rows for different turbines in one request.", "tags": ["core.projects.scope-items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeItemBulkCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/resource-sets": {"get": {"operationId": "list_project_resource_sets", "summary": "List Resource Sets for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "project_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project location ID", "title": "Project Location Id"}, "required": false, "description": "Filter by project location ID"}, {"in": "query", "name": "active_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start of the activity window (inclusive). Together with active_to, returns only sets that performed at least one workorder activity whose SOL-local day falls inside [active_from, active_to]. Attribution goes through dispatch.workorder_resource_set links including soft-deleted ones, so reassigned workorders still credit the team that worked them.", "title": "Active From"}, "required": false, "description": "Start of the activity window (inclusive). Together with active_to, returns only sets that performed at least one workorder activity whose SOL-local day falls inside [active_from, active_to]. Attribution goes through dispatch.workorder_resource_set links including soft-deleted ones, so reassigned workorders still credit the team that worked them."}, {"in": "query", "name": "active_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End of the activity window (inclusive). Paired with active_from.", "title": "Active To"}, "required": false, "description": "End of the activity window (inclusive). Paired with active_from."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectResourceSetResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_resource_set", "summary": "Create Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResourceSetResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResourceSetCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/resource-sets/{resource_set_id}": {"get": {"operationId": "get_project_resource_set", "summary": "Get Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "resource_set_id", "schema": {"title": "Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResourceSetResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_resource_set", "summary": "Update Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "resource_set_id", "schema": {"title": "Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResourceSetResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResourceSetUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_resource_set", "summary": "Delete Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "resource_set_id", "schema": {"title": "Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/materialize-planned-resource-set": {"post": {"operationId": "materialize_planned_resource_set", "summary": "Promote a planned resource set into an editable roster set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResourceSetResponse"}}}}}, "description": "Promote a planned project resource set into a roster set.\n\nThis is the only way a roster set is created, because the planned link is\nwhat carries the set's planned start and end dates. ``resource_ids`` is the\ncrew the user ticked; robots always come along. The same planned set can be\npromoted repeatedly, each time producing its own roster set.", "tags": ["core.projects.resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MaterializePlannedInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/resource-set-activity-days": {"get": {"operationId": "list_project_resource_set_activity_days", "summary": "Per-set workorder-activity days for a project window", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "active_from", "schema": {"format": "date", "title": "Active From", "type": "string"}, "required": true}, {"in": "query", "name": "active_to", "schema": {"format": "date", "title": "Active To", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectResourceSetActivityDaysResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Exact activity-day attribution per resource set for the team grid.", "tags": ["core.projects.resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/planned-resource-sets": {"get": {"operationId": "list_project_planned_resource_sets", "summary": "List Planned Resource Sets for Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "project_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project location ID", "title": "Project Location Id"}, "required": false, "description": "Filter by project location ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}, {"type": "null"}], "description": "Filter by status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectPlannedResourceSetResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.projects.planned-resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_planned_resource_set", "summary": "Create Planned Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.projects.planned-resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/planned-resource-sets/{planned_resource_set_id}": {"get": {"operationId": "get_project_planned_resource_set", "summary": "Get Planned Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.projects.planned-resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project_planned_resource_set", "summary": "Update Planned Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetResponse"}}}}}, "description": "Update a child item.", "tags": ["core.projects.planned-resource-sets"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_planned_resource_set", "summary": "Delete Planned Resource Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.projects.planned-resource-sets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/planned-resource-sets/{planned_resource_set_id}/items": {"get": {"operationId": "list_planned_resource_set_items", "summary": "List Items for Planned Resource Set", "parameters": [{"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "resource_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by resource type (ROBOT or TECHNICIAN)", "title": "Resource Type"}, "required": false, "description": "Filter by resource type (ROBOT or TECHNICIAN)"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}, {"type": "null"}], "description": "Filter by status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "is_lead", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by is_lead flag", "title": "Is Lead"}, "required": false, "description": "Filter by is_lead flag"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.planned-resource-sets.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_planned_resource_set_item", "summary": "Create Item", "parameters": [{"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.planned-resource-sets.items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/planned-resource-sets/{planned_resource_set_id}/items/{item_id}": {"get": {"operationId": "get_planned_resource_set_item", "summary": "Get Item", "parameters": [{"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.planned-resource-sets.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_planned_resource_set_item", "summary": "Update Item", "parameters": [{"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemResponse"}}}}}, "description": "Update a child item.", "tags": ["core.planned-resource-sets.items"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_planned_resource_set_item", "summary": "Delete Item", "parameters": [{"in": "path", "name": "planned_resource_set_id", "schema": {"title": "Planned Resource Set Id", "type": "integer"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.planned-resource-sets.items"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/planned-resource-set-items/{planned_resource_set_item_id}/commitments": {"get": {"operationId": "list_planned_resource_set_item_commitments", "summary": "List Commitments for Planned Resource Set Item", "parameters": [{"in": "path", "name": "planned_resource_set_item_id", "schema": {"title": "Planned Resource Set Item Id", "type": "integer"}, "required": true}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service", "title": "Service Id"}, "required": false, "description": "Filter by service"}, {"in": "query", "name": "pricing_unit_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by pricing unit", "title": "Pricing Unit Id"}, "required": false, "description": "Filter by pricing unit"}, {"in": "query", "name": "turbine_model_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine model", "title": "Turbine Model Id"}, "required": false, "description": "Filter by turbine model"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCommitmentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all child items for a parent with pagination, search, and sorting.", "tags": ["core.planned-resource-set-items.commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_planned_resource_set_item_commitment", "summary": "Create Commitment", "parameters": [{"in": "path", "name": "planned_resource_set_item_id", "schema": {"title": "Planned Resource Set Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCommitmentResponse"}}}}}, "description": "Create a new child item for the parent.", "tags": ["core.planned-resource-set-items.commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCommitmentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/planned-resource-set-items/{planned_resource_set_item_id}/commitments/{commitment_id}": {"get": {"operationId": "get_planned_resource_set_item_commitment", "summary": "Get Commitment", "parameters": [{"in": "path", "name": "planned_resource_set_item_id", "schema": {"title": "Planned Resource Set Item Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCommitmentResponse"}}}}}, "description": "Get a single child item.", "tags": ["core.planned-resource-set-items.commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_planned_resource_set_item_commitment", "summary": "Update Commitment", "parameters": [{"in": "path", "name": "planned_resource_set_item_id", "schema": {"title": "Planned Resource Set Item Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCommitmentResponse"}}}}}, "description": "Update a child item.", "tags": ["core.planned-resource-set-items.commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemCommitmentUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_planned_resource_set_item_commitment", "summary": "Delete Commitment", "parameters": [{"in": "path", "name": "planned_resource_set_item_id", "schema": {"title": "Planned Resource Set Item Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a child item.", "tags": ["core.planned-resource-set-items.commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/readiness": {"get": {"operationId": "get_project_readiness", "summary": "Get Project Readiness", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectReadinessResponse"}}}}}, "description": "Per-set readiness tallies for a project, plus a project-wide bucket.\n\n``project_id`` accepts either the project-builder UUID or the numeric core\nid (``ProjectManager.get`` resolves both).", "tags": ["core.projects.readiness"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/bto/travel-orders": {"get": {"operationId": "list_bto_travel_orders", "summary": "List Bto Travel Orders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BusinessTravelOrderListSchema"}, "title": "Response", "type": "array"}}}}}, "description": "List all travel orders for a project.", "tags": ["core.projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_bto_travel_order", "summary": "Create Bto Travel Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BusinessTravelOrderListSchema"}, "title": "Response", "type": "array"}}}}}, "description": "Create a travel order and return the refreshed list (legacy contract).", "tags": ["core.projects.bto"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderCreateSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/bto/travel-orders/{order_id}": {"get": {"operationId": "get_bto_travel_order", "summary": "Get Bto Travel Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderDetailSchema"}}}}}, "description": "Get a single travel order's details.", "tags": ["core.projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_bto_travel_order", "summary": "Update Bto Travel Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderDetailSchema"}}}}}, "description": "Update an existing travel order.", "tags": ["core.projects.bto"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderUpdateSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_bto_travel_order", "summary": "Delete Bto Travel Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete a travel order.", "tags": ["core.projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/bto/travel-orders/{order_id}/refresh": {"post": {"operationId": "refresh_bto_travel_order", "summary": "Refresh Bto Travel Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderDetailSchema"}}}}}, "description": "Refresh planned dates + unit counts from their Core sources.", "tags": ["core.projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/bto/travel-orders/{order_id}/send-emails": {"post": {"operationId": "send_bto_travel_order_emails", "summary": "Send Bto Travel Order Emails", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderDetailSchema"}}}}}, "description": "Send BTO notification emails and mark the travel order as sent.", "tags": ["core.projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/bto/travel-orders/{order_id}/questions": {"get": {"operationId": "get_bto_travel_order_questions", "summary": "Get Bto Travel Order Questions", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderQuestionsSchema"}}}}}, "description": "Get the travel order questionnaire.", "tags": ["core.projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "update_bto_travel_order_questions", "summary": "Update Bto Travel Order Questions", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderQuestionsSchema"}}}}}, "description": "Update the travel order questionnaire.", "tags": ["core.projects.bto"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BusinessTravelOrderQuestionsSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders": {"get": {"operationId": "bto_api_travel_orders_list_travel_orders", "summary": "List a project's travel orders with full per-site detail (no N+1 needed to render a site card)", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TravelOrderResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "bto_api_travel_orders_create_travel_order", "summary": "Create a travel order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderResponse"}}}}}, "tags": ["bto.travel-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderCreateSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}": {"get": {"operationId": "bto_api_travel_orders_get_travel_order", "summary": "Get a single travel order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderResponse"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "bto_api_travel_orders_update_travel_order", "summary": "Partially update a Draft travel order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderResponse"}}}}}, "tags": ["bto.travel-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderUpdateSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "bto_api_travel_orders_delete_travel_order", "summary": "Soft-delete a travel order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/refresh": {"post": {"operationId": "bto_api_travel_orders_refresh_travel_order", "summary": "Re-pull planned dates and team snapshot from their live sources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderResponse"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/send": {"post": {"operationId": "bto_api_travel_orders_send_travel_order", "summary": "Preflight-validate, freeze the team snapshot, and mark the order Sent", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderResponse"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/resend-all": {"post": {"operationId": "bto_api_travel_orders_resend_all_travel_order", "summary": "Resend the BTO email to every current crew member (Sent orders only)", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TravelOrderResponse"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/members/{resource_id}/resend": {"post": {"operationId": "bto_api_travel_orders_resend_to_member", "summary": "Resend the BTO email to one crew member (Sent orders only, magic link unchanged)", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResendResult"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/questionnaire-progress": {"get": {"operationId": "bto_api_answers_get_questionnaire_progress", "summary": "Read-only per-member questionnaire completion progress for the whole roster", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/MemberProgressResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/questionnaire/{resource_id}": {"get": {"operationId": "bto_api_answers_get_questionnaire", "summary": "Get one crew member's questionnaire with their current answers (read-only)", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/QuestionAnswerResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/projects/{project_id}/travel-orders/{order_id}/questionnaire/{resource_id}/{question_key}": {"put": {"operationId": "bto_api_answers_submit_answer_on_behalf", "summary": "Staff: edit one crew member's answer on their behalf (attributed to the acting user)", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "question_key", "schema": {"title": "Question Key", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/QuestionAnswerResponse"}}}}}, "tags": ["bto.travel-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SubmitAnswerSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "bto_api_answers_clear_answer_on_behalf", "summary": "Staff: reset one crew member's answer back to unanswered", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "order_id", "schema": {"title": "Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "resource_id", "schema": {"title": "Resource Id", "type": "integer"}, "required": true}, {"in": "path", "name": "question_key", "schema": {"title": "Question Key", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["bto.travel-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bto/v1/crew/{questionnaire_id}": {"get": {"operationId": "bto_api_crew_get_crew_overview", "summary": "Crew magic-link: order overview + this member's questionnaire", "parameters": [{"in": "path", "name": "questionnaire_id", "schema": {"title": "Questionnaire Id", "type": "string"}, "required": true}, {"in": "query", "name": "track", "schema": {"default": "opshub", "title": "Track", "type": "string"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CrewOverviewResponse"}}}}}, "tags": ["bto.crew"]}}, "/api/bto/v1/crew/{questionnaire_id}/pixel.gif": {"get": {"operationId": "bto_api_crew_crew_tracking_pixel", "summary": "Crew email tracking pixel: records the first email open", "parameters": [{"in": "path", "name": "questionnaire_id", "schema": {"title": "Questionnaire Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Return a 1x1 GIF and record the first email open for this member.\n\nThe emailed BTO embeds this as ``; when the mail\nclient loads it we stamp `opened_at` + one `email_opened` event (repeat\nloads are ignored). Distinct from a questionnaire-page open, which is\ntracked separately via `?track=` on the crew link. Always returns the\npixel, even for an unknown or malformed id, so a broken link never shows a\nbroken image. Only active (non-soft-deleted) questionnaires are recorded.", "tags": ["bto.crew"]}}, "/api/bto/v1/crew/{questionnaire_id}/pre-job-pdf": {"get": {"operationId": "bto_api_crew_get_crew_pre_job_pdf", "summary": "Crew magic-link: download the project's live Pre-job PDF", "parameters": [{"in": "path", "name": "questionnaire_id", "schema": {"title": "Questionnaire Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Stream the project's live Pre-job PDF for a crew magic link.\n\nThe crew has no session, so the auth-gated staff endpoint\n(`GET /api/projects/{uuid}/pre-job/pdf`) is unreachable for them. This\ntoken-gated public route resolves the questionnaire UUID -> travel order ->\nproject, then reuses the same `generate_prejob_pdf` generator keyed by the\nlegacy project UUID (`core.Project.project_builder_id`). Mirrors the staff\nendpoint's response shape (application/pdf + attachment filename).", "tags": ["bto.crew"]}}, "/api/bto/v1/crew/{questionnaire_id}/questionnaire/{question_key}": {"put": {"operationId": "bto_api_crew_submit_crew_answer", "summary": "Crew magic-link: submit (autosave) one answer", "parameters": [{"in": "path", "name": "questionnaire_id", "schema": {"title": "Questionnaire Id", "type": "string"}, "required": true}, {"in": "path", "name": "question_key", "schema": {"title": "Question Key", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CrewAnswerSchema"}}}}}, "tags": ["bto.crew"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CrewSubmitAnswerSchema"}}}, "required": true}}}, "/api/core/v1/projects/{project_id}/communication/messages": {"get": {"operationId": "list_project_communication_messages", "summary": "List Messages", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 50, "title": "Page Size", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectCommentResponse"}, "title": "Response", "type": "array"}}}}}, "description": "List project communication notes, newest first.", "tags": ["core.projects.communication"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project_communication_message", "summary": "Create Message", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectCommentResponse"}}}}}, "description": "Post a new project communication note.", "tags": ["core.projects.communication"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectCommentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/communication/messages/{comment_id}": {"patch": {"operationId": "update_project_communication_message", "summary": "Update Message", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectCommentResponse"}}}}}, "description": "Edit a project communication note (author only).", "tags": ["core.projects.communication"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectCommentUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project_communication_message", "summary": "Delete Message", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a project communication note (author only).", "tags": ["core.projects.communication"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/communication/feed": {"get": {"operationId": "get_project_communication_feed", "summary": "Get Feed", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 50, "title": "Page Size", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CommunicationFeedEntry"}, "title": "Response", "type": "array"}}}}}, "description": "Unified read-only feed: project notes + surfaced task comments.", "tags": ["core.projects.communication"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/roles/{role_id}/members": {"get": {"operationId": "list_role_members", "summary": "Role Members", "parameters": [{"in": "path", "name": "role_id", "schema": {"title": "Role Id", "type": "integer"}, "required": true}, {"in": "query", "name": "limit", "schema": {"default": 25, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RoleMemberListResponse"}}}}}, "description": "The people a role mention notifies, for the chip's hover list.\n\nRoles are global, so this takes no project. ``limit`` is capped at\n``ProjectCommentManager.MAX_MENTION_CANDIDATES`` (25) and ``offset`` pages\nthrough the rest, which is what lets the hover list scroll a large role.", "tags": ["core.projects.communication"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/communication/mention-candidates": {"get": {"operationId": "list_project_communication_mention_candidates", "summary": "Mention Candidates", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 10, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}, {"in": "query", "name": "kind", "schema": {"default": "user", "enum": ["user", "role"], "title": "Kind", "type": "string"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MentionCandidateListResponse"}}}}}, "description": "Users or roles that can be @-mentioned in this project's communication feed.\n\n``q`` filters by first name, last name, \"first last\", or email for users\n(case/accent-insensitive), and by name for roles. ``limit`` defaults to 10\nand is capped at ``ProjectCommentManager.MAX_MENTION_CANDIDATES`` (25).\n``offset`` pages through ``kind``'s results. The response always carries\n``user_count``/``role_count`` for both categories, so a single request\ncan fill the requested tab and both tab badges.", "tags": ["core.projects.communication"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-scope-change-requests": {"get": {"operationId": "list_projectscopechangerequests", "summary": "List ProjectScopeChangeRequests", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in description", "title": "Search"}, "required": false, "description": "Search in description"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "required": false, "description": "Sort field"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "project_offer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project offer ID", "title": "Project Offer Id"}, "required": false, "description": "Filter by project offer ID"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestType"}, {"type": "null"}], "description": "Filter by type"}, "required": false, "description": "Filter by type"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestStatus"}, {"type": "null"}], "description": "Filter by approval status (incl. REJECTED)"}, "required": false, "description": "Filter by approval status (incl. REJECTED)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectScopeChangeRequestResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["core.project-scope-change-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_projectscopechangerequest", "summary": "Create ProjectScopeChangeRequest", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestResponse"}}}}}, "description": "Create a new item.", "tags": ["core.project-scope-change-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-scope-change-requests/{id}": {"get": {"operationId": "get_projectscopechangerequest", "summary": "Get ProjectScopeChangeRequest", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["core.project-scope-change-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_projectscopechangerequest", "summary": "Update ProjectScopeChangeRequest", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestResponse"}}}}}, "description": "Update an item.", "tags": ["core.project-scope-change-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-scope-change-requests/{scope_change_request_id}/approve": {"post": {"operationId": "approve_projectscopechangerequest", "summary": "Approve the current review stage of a ProjectScopeChangeRequest", "parameters": [{"in": "path", "name": "scope_change_request_id", "schema": {"title": "Scope Change Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestResponse"}}}}}, "description": "Advance the request exactly one stage of the QC \u2192 Sales \u2192 PM chain.\n\nRequires the approval permission of the request's *current* stage\n(403 otherwise); ``expected_status`` must match the current status\n(422 otherwise \u2014 optimistic concurrency). The PM-stage approval runs\nthe finalize cascade; its response carries\n``replacement_service_order_line_id`` and the two workorder id lists.", "tags": ["core.project-scope-change-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestApproveBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-scope-change-requests/{scope_change_request_id}/reject": {"post": {"operationId": "reject_projectscopechangerequest", "summary": "Reject a ProjectScopeChangeRequest at its current review stage", "parameters": [{"in": "path", "name": "scope_change_request_id", "schema": {"title": "Scope Change Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestResponse"}}}}}, "description": "Terminally reject the request with a mandatory reason.\n\nGated by the same stage permission as approve; zero side effects (the\ncascade never ran). Rejection frees the source SOL for a corrected\nnew request.", "tags": ["core.project-scope-change-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectScopeChangeRequestRejectBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/project-scope-change-requests/{scope_change_request_id}/pdf": {"get": {"operationId": "get_projectscopechangerequest_pdf", "summary": "Download a ProjectScopeChangeRequest as a PDF", "parameters": [{"in": "path", "name": "scope_change_request_id", "schema": {"title": "Scope Change Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Render the request as a printable record and serve it as a download.\n\nCarries the summary, the description, and the two damage-condition\nassessments side by side with their photos. The review trail, the\nrequested service items and the general evidence images are\ndeliberately not in it. Rendered on demand \u2014 nothing is stored.", "tags": ["core.project-scope-change-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects": {"get": {"operationId": "core_endpoints_projects_list_projects", "summary": "List Projects", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Case-insensitive match on project code or names of linked locations (active project\u2013location links only). SOL-number lookup lives in GET /core/v1/projects/search. Each project is returned at most once.", "title": "Search"}, "required": false, "description": "Case-insensitive match on project code or names of linked locations (active project\u2013location links only). SOL-number lookup lives in GET /core/v1/projects/search. Each project is returned at most once."}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "requesting_customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by requesting customer ID (ignored when requesting_customer_ids is set)", "title": "Requesting Customer Id"}, "required": false, "description": "Filter by requesting customer ID (ignored when requesting_customer_ids is set)"}, {"in": "query", "name": "billing_customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by billing customer ID (ignored when billing_customer_ids is set)", "title": "Billing Customer Id"}, "required": false, "description": "Filter by billing customer ID (ignored when billing_customer_ids is set)"}, {"in": "query", "name": "vendor_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by vendor ID (ignored when vendor_ids is set)", "title": "Vendor Id"}, "required": false, "description": "Filter by vendor ID (ignored when vendor_ids is set)"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID (ignored when country_ids is set)", "title": "Country Id"}, "required": false, "description": "Filter by country ID (ignored when country_ids is set)"}, {"in": "query", "name": "status_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by status ID (ignored when status_ids is set)", "title": "Status Id"}, "required": false, "description": "Filter by status ID (ignored when status_ids is set)"}, {"in": "query", "name": "project_manager_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project manager ID (ignored when project_manager_ids is set)", "title": "Project Manager Id"}, "required": false, "description": "Filter by project manager ID (ignored when project_manager_ids is set)"}, {"in": "query", "name": "salesperson_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by salesperson ID (ignored when salesperson_ids is set)", "title": "Salesperson Id"}, "required": false, "description": "Filter by salesperson ID (ignored when salesperson_ids is set)"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project type (REGULAR, WARRANTY, DEMO, RND, ACADEMY, or INTERNAL)", "title": "Type"}, "required": false, "description": "Filter by project type (REGULAR, WARRANTY, DEMO, RND, ACADEMY, or INTERNAL)"}, {"in": "query", "name": "types", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated project types (OR within), e.g. REGULAR,WARRANTY. Empty/omitted = no type filter. When set, type is ignored.", "title": "Types"}, "required": false, "description": "Comma-separated project types (OR within), e.g. REGULAR,WARRANTY. Empty/omitted = no type filter. When set, type is ignored."}, {"in": "query", "name": "status_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated status IDs (OR within). Empty/omitted = no status filter. When set, status_id is ignored.", "title": "Status Ids"}, "required": false, "description": "Comma-separated status IDs (OR within). Empty/omitted = no status filter. When set, status_id is ignored."}, {"in": "query", "name": "country_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated country IDs (OR within). Empty/omitted = no country filter. When set, country_id is ignored.", "title": "Country Ids"}, "required": false, "description": "Comma-separated country IDs (OR within). Empty/omitted = no country filter. When set, country_id is ignored."}, {"in": "query", "name": "requesting_customer_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated requesting customer IDs (OR within). Empty/omitted = no filter on this facet. When set, requesting_customer_id is ignored.", "title": "Requesting Customer Ids"}, "required": false, "description": "Comma-separated requesting customer IDs (OR within). Empty/omitted = no filter on this facet. When set, requesting_customer_id is ignored."}, {"in": "query", "name": "billing_customer_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated billing customer IDs (OR within). Empty/omitted = no filter on this facet. When set, billing_customer_id is ignored.", "title": "Billing Customer Ids"}, "required": false, "description": "Comma-separated billing customer IDs (OR within). Empty/omitted = no filter on this facet. When set, billing_customer_id is ignored."}, {"in": "query", "name": "vendor_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated vendor IDs (OR within). Empty/omitted = no vendor filter. When set, vendor_id is ignored.", "title": "Vendor Ids"}, "required": false, "description": "Comma-separated vendor IDs (OR within). Empty/omitted = no vendor filter. When set, vendor_id is ignored."}, {"in": "query", "name": "project_manager_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated project manager user IDs (OR within). Empty/omitted = no filter on this facet. When set, project_manager_id is ignored.", "title": "Project Manager Ids"}, "required": false, "description": "Comma-separated project manager user IDs (OR within). Empty/omitted = no filter on this facet. When set, project_manager_id is ignored."}, {"in": "query", "name": "salesperson_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated salesperson user IDs (OR within). Empty/omitted = no filter on this facet. When set, salesperson_id is ignored.", "title": "Salesperson Ids"}, "required": false, "description": "Comma-separated salesperson user IDs (OR within). Empty/omitted = no filter on this facet. When set, salesperson_id is ignored."}, {"in": "query", "name": "scope", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "'mine' or 'all'", "title": "Scope"}, "required": false, "description": "'mine' or 'all'"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return a paginated list of projects, filterable by query parameters.\n\nPure technician users see only projects where they are assigned as a resource\n(via workorder assignments or project resource sets). Admin users bypass this scope.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_projects_create_project", "summary": "Create Project", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResponse"}}}}}, "description": "Create a new project. project_builder_id is optional for natively created projects.", "tags": ["core.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/search": {"get": {"operationId": "core_endpoints_projects_search_projects", "summary": "Search Projects", "parameters": [{"in": "query", "name": "search", "schema": {"default": "", "title": "Search", "type": "string"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectSearchResult"}, "title": "Response", "type": "array"}}}}}, "description": "Typed search for the global header search box, projects listed first.\n\nReturns project rows (matched on project code or an active linked location\nname) followed by SOL rows (matched on SOL number), each group capped at 10.\nMatching is token-prefix and unicode-aware: the term must start the value\nor follow a separator, so ``550`` finds ``VEUS-5502`` but not ``VEUS-3550``.\nA blank ``search``, or one shorter than three characters after stripping\nleading separators, returns an empty list.\n\nDeliberately requires ``regular_user`` only \u2014 the same key that unlocks\n``get_project`` \u2014 so anyone who can search a project can also open it\n(``technician_user`` alone can list but not open, the mismatch behind the\nold \"visible in the table, 403 on open\" bug). Technician-group members\nholding ``regular_user`` still only see their assigned projects, matching\nthe project list scope.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}": {"get": {"operationId": "core_endpoints_projects_get_project", "summary": "Get Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResponse"}}}}}, "description": "Retrieve a single project by its numeric ID or UUID.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "core_endpoints_projects_update_project", "summary": "Update Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResponse"}}}}}, "description": "Partially update a project. The project_builder_id link cannot be removed.", "tags": ["core.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_projects_delete_project", "summary": "Delete Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a project, marking it as inactive.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/overview": {"get": {"operationId": "core_endpoints_projects_get_project_overview", "summary": "Get Project Overview", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOverviewResponse"}}}}}, "description": "Decoupled project overview card (meta, scope, deployments, dates).\n\nFields already on the base project response (code, country, PM, salesperson,\nstatus, LPS standard, description, customers) are intentionally omitted \u2014\nread those from ``GET /core/v1/projects/{id}``.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "core_endpoints_projects_update_project_overview", "summary": "Update Project Overview", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOverviewResponse"}}}}}, "description": "Update overview fields across Core (description, LPS) and legacy tables.\n\nDoes not reuse the legacy ``update_overview_info``; writes each backing\ntable directly via ORM in a single transaction.", "tags": ["core.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOverviewEdit"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/overview/financials": {"get": {"operationId": "core_endpoints_projects_get_project_overview_financials", "summary": "Get Project Overview Financials", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOverviewFinancialsResponse"}}}}}, "description": "Decoupled project financial overview (CO/charged/PO values, offer status).", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/status-history": {"get": {"operationId": "core_endpoints_projects_get_project_status_history", "summary": "Get Project Status History", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectStatusHistoryEntry"}, "title": "Response", "type": "array"}}}}}, "description": "Chronological history of a project's status transitions (oldest first).\n\nEach entry records the status moved from/to, the trigger (``change_reason``),\nan optional note, when it happened, and who caused it. History accrues from\nwhen tracking was introduced \u2014 projects with no recorded transitions yet\nreturn an empty list.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/validate": {"get": {"operationId": "core_endpoints_projects_validate_project", "summary": "Validate Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectValidateResponse"}}}}}, "description": "Validate project configuration and return a list of warning codes.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/refresh-google-drive": {"post": {"operationId": "core_endpoints_projects_refresh_project_google_drive", "summary": "Refresh Project Google Drive", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Provision Google Drive folders for a project if the ROOT link is not yet set.\n\nSkips silently when the ROOT link already exists. Uses the Pipedrive deal URL\nwhen available, then falls back to auto-discovery if it is missing or invalid.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/complete": {"post": {"operationId": "core_endpoints_projects_mark_project_completed", "summary": "Mark Project Completed", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResponse"}}}}}, "description": "Manually transition a project from Closure to Completed.\n\nThe cascade only advances projects up to Closure (all SOLs Completed or\nCancelled). Moving to Completed is an explicit close-out action \u2014 there\nis no automatic trigger.", "tags": ["core.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/status-override": {"post": {"operationId": "core_endpoints_projects_override_project_status", "summary": "Override Project Status", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResponse"}}}}}, "description": "Manually set a project's status, bypassing the stage gates.\n\nPrivileged override gated behind the ``force_complete_project`` permission.\nAny status except Cancelled can be set, in either direction, including\nreopening a Completed project. Rules, audit trail, and the deliberate\nno-side-effects contract live in ``ProjectManager.override_status``. The\nautomatic status rules (SOL cascade, nightly reconciler) stay active and\nmay later move the status again.", "tags": ["core.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectStatusOverride"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/projects/{project_id}/pre-job-received": {"put": {"operationId": "core_endpoints_projects_update_project_pre_job_received", "summary": "Update Project Pre Job Received", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectResponse"}}}}}, "description": "Set or clear the customer pre-job questionnaire 'received' timestamp.\n\nThis is the Core replacement for the legacy ``PUT /projects/{id}/user-status``\npre-job workflow path. Only the *null-ness* of ``payload.pre_job_received_at``\nis read \u2014 it signals intent; the timestamp itself is stamped **server-side**\n(``timezone.now()``) to stay robust against client clock skew:\n\n- ``null -> non-null`` (customer **submit**): stamps the timestamp, sends the\n pre-job submission notification, and re-runs the Pipedrive status cascade\n (advancing the project to Planning when probability is 100).\n- ``non-null -> null`` (staff **reopen**): clears the timestamp; no email,\n no cascade.\n- already-received re-submit: keeps the existing timestamp; no side effects.", "tags": ["core.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPreJobReceivedUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders": {"get": {"operationId": "core_endpoints_purchase_orders_list_purchase_orders", "summary": "List purchase orders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Case-insensitive search across version order numbers", "title": "Search"}, "required": false, "description": "Case-insensitive search across version order numbers"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort field (prefix with - for descending)"}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "currency_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PurchaseOrderResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.purchase-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_purchase_orders_create_purchase_order", "summary": "Create a purchase order with its initial version", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderResponse"}}}}}, "tags": ["core.purchase-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders/{id}": {"get": {"operationId": "core_endpoints_purchase_orders_get_purchase_order", "summary": "Get a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderResponse"}}}}}, "tags": ["core.purchase-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "core_endpoints_purchase_orders_update_purchase_order", "summary": "Update a purchase order (customer / currency only)", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderResponse"}}}}}, "tags": ["core.purchase-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_purchase_orders_delete_purchase_order", "summary": "Soft-delete a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["core.purchase-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders/{id}/versions": {"get": {"operationId": "core_endpoints_purchase_orders_list_versions", "summary": "List versions for a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by order_number", "title": "Search"}, "required": false, "description": "Search by order_number"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PurchaseOrderVersionResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.purchase-orders.versions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_purchase_orders_add_version", "summary": "Add a new version (amendment) to a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderVersionResponse"}}}}}, "tags": ["core.purchase-orders.versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderVersionCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders/{id}/versions/{version_id}": {"get": {"operationId": "core_endpoints_purchase_orders_get_version", "summary": "Get a version", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "version_id", "schema": {"title": "Version Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderVersionResponse"}}}}}, "tags": ["core.purchase-orders.versions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "core_endpoints_purchase_orders_update_version", "summary": "Update a version (scalar fields only)", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "version_id", "schema": {"title": "Version Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderVersionResponse"}}}}}, "tags": ["core.purchase-orders.versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderVersionUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_purchase_orders_delete_version", "summary": "Soft-delete a version", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "version_id", "schema": {"title": "Version Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["core.purchase-orders.versions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders/{id}/versions/{version_id}/file": {"post": {"operationId": "core_endpoints_purchase_orders_replace_version_file", "summary": "Set or replace the file attached to a version", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "version_id", "schema": {"title": "Version Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["core.purchase-orders.versions"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderVersionFileReplaceRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_purchase_orders_remove_version_file", "summary": "Detach the file from a version (no-op if none)", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "version_id", "schema": {"title": "Version Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["core.purchase-orders.versions"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders/{id}/projects": {"get": {"operationId": "core_endpoints_purchase_orders_list_project_links", "summary": "List project links for a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PurchaseOrderProjectResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["core.purchase-orders.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "core_endpoints_purchase_orders_add_project_link", "summary": "Link a project to a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderProjectResponse"}}}}}, "tags": ["core.purchase-orders.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderProjectCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/core/v1/purchase-orders/{id}/projects/{project_id}": {"patch": {"operationId": "core_endpoints_purchase_orders_update_project_link", "summary": "Update the allocation for a PO-project link", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderProjectResponse"}}}}}, "tags": ["core.purchase-orders.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PurchaseOrderProjectUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "core_endpoints_purchase_orders_remove_project_link", "summary": "Remove a project link from a purchase order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["core.purchase-orders.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles/summary": {"get": {"operationId": "get_vehicle_fleet_summary", "summary": "Get Vehicle Fleet Summary", "parameters": [{"in": "query", "name": "vehicle_source", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Source"}, "required": false}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetSummary"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles": {"get": {"operationId": "resource_mobilization_endpoints_vehicles_list_vehicles", "summary": "List Vehicles", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by license plate, make, or model", "title": "Search"}, "required": false, "description": "Search by license plate, make, or model"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by vehicle type", "title": "Type"}, "required": false, "description": "Filter by vehicle type"}, {"in": "query", "name": "vehicle_source", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by vehicle source", "title": "Vehicle Source"}, "required": false, "description": "Filter by vehicle source"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by office location", "title": "Location Id"}, "required": false, "description": "Filter by office location"}, {"in": "query", "name": "include_archived", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Include archived vehicles", "title": "Include Archived"}, "required": false, "description": "Include archived vehicles"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VehicleResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "resource_mobilization_endpoints_vehicles_create_vehicle", "summary": "Create Vehicle", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles/{id}/archive": {"post": {"operationId": "resource_mobilization_endpoints_vehicles_archive_vehicle", "summary": "Archive Vehicle", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles/{id}/unarchive": {"post": {"operationId": "resource_mobilization_endpoints_vehicles_unarchive_vehicle", "summary": "Unarchive Vehicle", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles/{id}": {"get": {"operationId": "resource_mobilization_endpoints_vehicles_get_vehicle", "summary": "Get Vehicle", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "resource_mobilization_endpoints_vehicles_update_vehicle", "summary": "Update Vehicle", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "resource_mobilization_endpoints_vehicles_delete_vehicle", "summary": "Delete Vehicle", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles/{id}/insurances": {"get": {"operationId": "resource_mobilization_endpoints_vehicles_list_vehicle_insurances", "summary": "List Vehicle Insurances", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VehicleInsuranceResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "resource_mobilization_endpoints_vehicles_create_vehicle_insurance", "summary": "Create Vehicle Insurance", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleInsuranceResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleInsuranceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicles/{id}/insurances/{insurance_id}": {"patch": {"operationId": "resource_mobilization_endpoints_vehicles_update_vehicle_insurance", "summary": "Update Vehicle Insurance", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "insurance_id", "schema": {"title": "Insurance Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleInsuranceResponse"}}}}}, "tags": ["resource-mobilization.vehicles"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleInsuranceUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "resource_mobilization_endpoints_vehicles_delete_vehicle_insurance", "summary": "Delete Vehicle Insurance", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "insurance_id", "schema": {"title": "Insurance Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["resource-mobilization.vehicles"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/discrepancies": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_list_discrepancies", "summary": "List Discrepancies", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentDiscrepancies"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_list_assignments", "summary": "List Assignments", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by vehicle license plate or assignee name", "title": "Search"}, "required": false, "description": "Search by vehicle license plate or assignee name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "vehicle_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by vehicle ID", "title": "Vehicle Id"}, "required": false, "description": "Filter by vehicle ID"}, {"in": "query", "name": "assignee_user_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by assignee user ID", "title": "Assignee User Id"}, "required": false, "description": "Filter by assignee user ID"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/plan": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_plan_assignment", "summary": "Plan Assignment", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetPlanSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/accept": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_accept_vehicle", "summary": "Accept Vehicle", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAcceptSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/user-projects": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_get_user_projects", "summary": "Get User Projects", "parameters": [{"in": "query", "name": "user_id", "schema": {"title": "User Id", "type": "integer"}, "required": true}, {"in": "query", "name": "from_date", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Date"}, "required": true}, {"in": "query", "name": "to_date", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Date"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/UserProjectOverlap"}, "title": "Response", "type": "array"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/planner-status": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_planner_status", "summary": "Planner Status", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlannerStatusResponse"}}}}}, "description": "Per-request planner status for the fleet queue (batch).\n\nLets the requests list flag which fleet requests match the technician's\nplanner roster without a round-trip per row.", "tags": ["resource-mobilization.vehicle-fleet-assignments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlannerStatusRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/{id}": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_get_assignment", "summary": "Get Assignment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/{id}/accept": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_accept_planned_assignment", "summary": "Accept Planned Assignment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAcceptPlannedSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/{id}/update": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_update_assignment", "summary": "Update Assignment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetUpdateSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/{id}/return": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_return_vehicle", "summary": "Return Vehicle", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetReturnSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-assignments/{id}/cancel": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_assignments_cancel_assignment", "summary": "Cancel Assignment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetAssignmentResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-assignments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-invoices": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_list_invoices", "summary": "List Invoices", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by invoice number", "title": "Search"}, "required": false, "description": "Search by invoice number"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "vehicle_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by vehicle ID", "title": "Vehicle Id"}, "required": false, "description": "Filter by vehicle ID"}, {"in": "query", "name": "assignment_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by assignment ID", "title": "Assignment Id"}, "required": false, "description": "Filter by assignment ID"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by invoice type", "title": "Type"}, "required": false, "description": "Filter by invoice type"}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter invoices from this date (inclusive)", "title": "Date From"}, "required": false, "description": "Filter invoices from this date (inclusive)"}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter invoices up to this date (inclusive)", "title": "Date To"}, "required": false, "description": "Filter invoices up to this date (inclusive)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VehicleFleetInvoiceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_create_invoice", "summary": "Create Invoice", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetInvoiceResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetInvoiceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-invoices/extract": {"post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_extract_invoice", "summary": "Extract Invoice", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetInvoiceExtractionResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-invoices/{id}": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_get_invoice", "summary": "Get Invoice", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetInvoiceResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_update_invoice", "summary": "Update Invoice", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetInvoiceResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/VehicleFleetInvoiceUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_delete_invoice", "summary": "Delete Invoice", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-invoices/{id}/files": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_list_invoice_files", "summary": "List Invoice Files", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/FileResourceResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_upload_invoice_file", "summary": "Upload Invoice File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileResourceResponse"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-invoices/{id}/files/{file_id}/download": {"get": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_download_invoice_file", "summary": "Download Invoice File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_id", "schema": {"title": "File Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-invoices/{id}/files/{file_resource_id}": {"delete": {"operationId": "resource_mobilization_endpoints_vehicle_fleet_invoices_delete_invoice_file", "summary": "Delete Invoice File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "file_resource_id", "schema": {"title": "File Resource Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/obd-gps-devices": {"get": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_list_devices", "summary": "List Devices", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by IMEI", "title": "Search"}, "required": false, "description": "Search by IMEI"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ObdGpsDeviceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_create_device", "summary": "Create Device", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceResponse"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/obd-gps-devices/{id}/assign": {"post": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_assign_device", "summary": "Assign Device", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceResponse"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceAssignSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/obd-gps-devices/{id}/end-assignment": {"post": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_end_assignment", "summary": "End Assignment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceResponse"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceEndAssignmentSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/obd-gps-devices/sync-navirec": {"post": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_sync_navirec", "summary": "Sync Navirec", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NavirecSyncResponse"}}}}}, "description": "Push assignee names to Navirec for every device with an active assignment.\n\nMatches by IMEI \u2194 Navirec vehicle.registration; sets the vehicle name\n(\"Transportl\u012bdzek\u013ca nosaukums\") to \"{assignee} {imei}\". Unmatched IMEIs are\nskipped.", "tags": ["resource-mobilization.obd-gps-devices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/obd-gps-devices/{id}/assignments": {"get": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_list_device_assignments", "summary": "List Device Assignments", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ObdGpsDeviceAssignmentFullResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/obd-gps-devices/{id}": {"get": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_get_device", "summary": "Get Device", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceResponse"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_update_device", "summary": "Update Device", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceResponse"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ObdGpsDeviceUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "resource_mobilization_endpoints_obd_gps_devices_delete_device", "summary": "Delete Device", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["resource-mobilization.obd-gps-devices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-locations/vehicle-map": {"get": {"operationId": "get_vehicle_map_locations", "summary": "Get locations with vehicle counts for map view", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VehicleMapLocation"}, "title": "Response", "type": "array"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/resource-mobilization/v1/vehicle-fleet-locations": {"get": {"operationId": "list_vehicle_fleet_locations", "summary": "List locations for fleet use", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name", "title": "Search"}, "required": false, "description": "Search by name"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/VehicleFleetLocationResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["resource-mobilization.vehicle-fleet-locations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines": {"get": {"operationId": "technician_api_projects_list_service_order_lines", "summary": "List Service Order Lines", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by SOL ID, service code, or service description (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by SOL ID, service code, or service description (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix with '-' for descending. Allowed: service_code, service_description, status, quantity", "title": "Sort"}, "required": false, "description": "Sort field, prefix with '-' for descending. Allowed: service_code, service_description, status, quantity"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code (exact match)", "title": "Service Code"}, "required": false, "description": "Filter by service code (exact match)"}, {"in": "query", "name": "activity_date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SOLs with activities on or after this date", "title": "Activity Date From"}, "required": false, "description": "Filter SOLs with activities on or after this date"}, {"in": "query", "name": "activity_date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SOLs with activities on or before this date", "title": "Activity Date To"}, "required": false, "description": "Filter SOLs with activities on or before this date"}, {"in": "query", "name": "total_count", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Client-supplied total count from a previous page response. When provided, skips the COUNT query and returns this value as Total-Count.", "title": "Total Count"}, "required": false, "description": "Client-supplied total count from a previous page response. When provided, skips the COUNT query and returns this value as Total-Count."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceOrderLineResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List service order lines with optional filters.\n\nReturns paginated service order lines with turbine, component type,\nand project info.", "tags": ["technician.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/filters": {"get": {"operationId": "technician_api_projects_get_service_order_line_filters", "summary": "Get Service Order Line Filters", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineFiltersResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return distinct filter options from existing service order lines.", "tags": ["technician.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/{line_id}": {"get": {"operationId": "technician_api_projects_get_service_order_line_detail", "summary": "Get Service Order Line Detail", "parameters": [{"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineDetailResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a single scoped service order line detail for technician views.", "tags": ["technician.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/workorders": {"get": {"operationId": "technician_api_workorders_list_workorders", "summary": "List Workorders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by workorder name", "title": "Search"}, "required": false, "description": "Search by workorder name"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix '-' for desc. Allowed: name, status, planned_start_date, planned_end_date", "title": "Sort"}, "required": false, "description": "Sort field, prefix '-' for desc. Allowed: name, status, planned_start_date, planned_end_date"}, {"in": "query", "name": "service_order_line_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by SOL ID", "title": "Service Order Line Id"}, "required": false, "description": "Filter by SOL ID"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status (exact)", "title": "Status"}, "required": false, "description": "Filter by status (exact)"}, {"in": "query", "name": "planned_start_date__gte", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned start date on or after this date", "title": "Planned Start Date Gte"}, "required": false, "description": "Filter planned start date on or after this date"}, {"in": "query", "name": "planned_start_date__lte", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned start date on or before this date", "title": "Planned Start Date Lte"}, "required": false, "description": "Filter planned start date on or before this date"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List workorders for OpsHub admin UI with optional filters.", "tags": ["technician.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/workorders/filters": {"get": {"operationId": "technician_api_workorders_get_workorder_filters", "summary": "Get Workorder Filters", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderFiltersResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return distinct filter options for OpsHub admin UI workorder lists.", "tags": ["technician.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/workorders/sol-activities": {"get": {"operationId": "technician_api_workorders_list_sol_activities", "summary": "List Sol Activities", "parameters": [{"in": "query", "name": "sol_id", "schema": {"description": "Service Order Line ID (required)", "title": "Sol Id", "type": "integer"}, "required": true, "description": "Service Order Line ID (required)"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SolActivitiesPageResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all activities for a Service Order Line, grouped by the frontend.\n\nTechnicians (non-admin) see only FIELD-type workorders here so the mobile\nactivity feed is scoped to physical field work. PMs / Admins see every\ntype, since they need to triage office and data-upload workorders too.", "tags": ["technician.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/workorders/{workorder_id}": {"get": {"operationId": "technician_api_workorders_get_workorder_detail", "summary": "Get Workorder Detail", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}, {"in": "query", "name": "include_all_resources", "schema": {"default": false, "title": "Include All Resources", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderDetailResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a single workorder with detail info.\n\nBy default, available assignment options are scoped to this workorder.\nSet include_all_resources=true to request company-wide options.", "tags": ["technician.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/workorders/{workorder_id}/available-activities": {"get": {"operationId": "technician_api_workorders_get_available_activities", "summary": "Get Available Activities", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AvailableActivityResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get available service item activities for a workorder.", "tags": ["technician.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/workorders/{workorder_id}/resource-presets": {"get": {"operationId": "technician_api_workorders_get_resource_presets", "summary": "Get available resource presets (ProjectResourceSets) for a workorder", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ResourcePresetResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return ProjectResourceSet entries for the workorder's project.", "tags": ["technician.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/dashboard/summary": {"get": {"operationId": "technician_api_service_results_get_dashboard_summary", "summary": "Get Dashboard Summary", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/after this date", "title": "Start Date"}, "required": false, "description": "Filter results created on/after this date"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/before this date", "title": "End Date"}, "required": false, "description": "Filter results created on/before this date"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}, "required": false, "description": "Filter by service code"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DashboardSummaryResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return operations dashboard KPI summary for service results.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/dashboard/queue": {"get": {"operationId": "technician_api_service_results_get_dashboard_queue", "summary": "Get Dashboard Queue", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/after this date", "title": "Start Date"}, "required": false, "description": "Filter results created on/after this date"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/before this date", "title": "End Date"}, "required": false, "description": "Filter results created on/before this date"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}, "required": false, "description": "Filter by service code"}, {"in": "query", "name": "validation_reason", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by validation reason: missing_required_fields, missing_standard, missing_threshold_match, invalid_value, condition_nok, multiple_readings", "title": "Validation Reason"}, "required": false, "description": "Filter by validation reason: missing_required_fields, missing_standard, missing_threshold_match, invalid_value, condition_nok, multiple_readings"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by created_at or service_code. Prefix with '-' for descending.", "title": "Sort"}, "required": false, "description": "Sort by created_at or service_code. Prefix with '-' for descending."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DashboardQueueItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return operator queue with pending service result rows.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/{sol_id}/service-results": {"get": {"operationId": "technician_api_service_results_list_service_results_for_sol", "summary": "List Service Results For Sol", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/after this date", "title": "Start Date"}, "required": false, "description": "Filter results created on/after this date"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/before this date", "title": "End Date"}, "required": false, "description": "Filter results created on/before this date"}, {"in": "query", "name": "template_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by template ID", "title": "Template Id"}, "required": false, "description": "Filter by template ID"}, {"in": "query", "name": "standard_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by standard ID", "title": "Standard Id"}, "required": false, "description": "Filter by standard ID"}, {"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder ID", "title": "Workorder Id"}, "required": false, "description": "Filter by workorder ID"}, {"in": "query", "name": "turbine_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine component ID", "title": "Turbine Component Id"}, "required": false, "description": "Filter by turbine component ID"}, {"in": "query", "name": "side", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.side (for example: SUCTION_SIDE, PRESSURE_SIDE)", "title": "Side"}, "required": false, "description": "Filter by data.side (for example: SUCTION_SIDE, PRESSURE_SIDE)"}, {"in": "query", "name": "condition", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.condition (for example: OK, NOK)", "title": "Condition"}, "required": false, "description": "Filter by data.condition (for example: OK, NOK)"}, {"in": "query", "name": "result_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.status (for example: CLOGGED, CLEANED)", "title": "Result Status"}, "required": false, "description": "Filter by data.status (for example: CLOGGED, CLEANED)"}, {"in": "query", "name": "comment", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.comment (case-insensitive contains)", "title": "Comment"}, "required": false, "description": "Filter by data.comment (case-insensitive contains)"}, {"in": "query", "name": "open", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.open boolean value", "title": "Open"}, "required": false, "description": "Filter by data.open boolean value"}, {"in": "query", "name": "no_reading", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.no_reading boolean value", "title": "No Reading"}, "required": false, "description": "Filter by data.no_reading boolean value"}, {"in": "query", "name": "test_failed", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.test_failed boolean value", "title": "Test Failed"}, "required": false, "description": "Filter by data.test_failed boolean value"}, {"in": "query", "name": "oxidation_removed", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.is_oxidation_removal boolean value", "title": "Oxidation Removed"}, "required": false, "description": "Filter by data.is_oxidation_removal boolean value"}, {"in": "query", "name": "validation_state", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by validation state: AUTO_VERIFIED, PENDING_OPERATOR", "title": "Validation State"}, "required": false, "description": "Filter by validation state: AUTO_VERIFIED, PENDING_OPERATOR"}, {"in": "query", "name": "validation_reason", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by validation reason: missing_required_fields, missing_standard, missing_threshold_match, invalid_value, condition_nok, multiple_readings", "title": "Validation Reason"}, "required": false, "description": "Filter by validation reason: missing_required_fields, missing_standard, missing_threshold_match, invalid_value, condition_nok, multiple_readings"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by result id, template code, threshold name, or standard", "title": "Search"}, "required": false, "description": "Search by result id, template code, threshold name, or standard"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by created_at, updated_at, id, template_code, standard_name, workorder_id, turbine_component_id, result_threshold_id, or reading. Prefix with '-' for descending.", "title": "Sort"}, "required": false, "description": "Sort by created_at, updated_at, id, template_code, standard_name, workorder_id, turbine_component_id, result_threshold_id, or reading. Prefix with '-' for descending."}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceResultRecord"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List scoped service results for one service order line.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "technician_api_service_results_create_service_result", "summary": "Create Service Result", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceResultMutationResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a service result row and classify it for operator workflow.", "tags": ["technician.service_results"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceResultCreateInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/{sol_id}/result-capture-context": {"get": {"operationId": "technician_api_service_results_get_result_capture_context", "summary": "Get Result Capture Context", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResultCaptureContextResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return context payload for dynamic technician service result form.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/{sol_id}/finalize": {"post": {"operationId": "technician_api_service_results_finalize_service_order_line", "summary": "Finalize Service Order Line", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalizeServiceResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Finalize a service order line by transitioning its status to COMPLETED.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/{sol_id}/unfinalize": {"post": {"operationId": "technician_api_service_results_unfinalize_service_order_line", "summary": "Unfinalize Service Order Line", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalizeServiceResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Revert a finalized service order line back to FIELD_COMPLETED.\n\nUses SELECT FOR UPDATE inside a transaction to prevent race conditions\nwhere two concurrent requests could both pass the status check.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-results/{result_id}": {"get": {"operationId": "technician_api_service_results_get_service_result", "summary": "Get Service Result", "parameters": [{"in": "path", "name": "result_id", "schema": {"title": "Result Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceResultRecord"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a single scoped service result with validation metadata.", "tags": ["technician.service_results"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "technician_api_service_results_patch_service_result", "summary": "Patch Service Result", "parameters": [{"in": "path", "name": "result_id", "schema": {"title": "Result Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceResultMutationResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Patch a scoped service result and re-run threshold classification.", "tags": ["technician.service_results"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceResultUpdateInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/service-order-lines/{sol_id}/cleaning-images": {"get": {"operationId": "technician_api_service_results_get_sol_cleaning_images", "summary": "Get Sol Cleaning Images", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SolCleaningImagesResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "DEPRECATED \u2014 use ``GET /core/v1/files/service_order_line/{sol_id}/``.\n\nReturns SOL-level cleaning image storage IDs grouped by category from the\nlegacy ``cleaning_images`` JSON column. Kept as a one-release fallback.", "tags": ["technician.service_results"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "technician_api_service_results_patch_sol_cleaning_images", "summary": "Patch Sol Cleaning Images", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SolCleaningImagesResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "DEPRECATED \u2014 use ``POST /core/v1/files/service_order_line/{sol_id}/``.\n\nMerge cleaning image references into the SOL's legacy ``cleaning_images``\nJSON column. New uploads should go through the core file endpoint so each\nimage becomes a queryable ``FileEntityLink`` row.", "tags": ["technician.service_results"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SolCleaningImagesInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/service-order-lines": {"get": {"operationId": "reports_api_list_report_service_order_lines", "summary": "List Report Service Order Lines", "parameters": [{"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (optional)", "title": "Project Id"}, "required": false, "description": "Project ID (optional)"}, {"in": "query", "name": "project_manager_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project manager user ID", "title": "Project Manager Id"}, "required": false, "description": "Project manager user ID"}, {"in": "query", "name": "robot_set_ids", "schema": {"description": "Robot set IDs", "items": {"type": "integer"}, "title": "Robot Set Ids", "type": "array"}, "required": false, "description": "Robot set IDs"}, {"in": "query", "name": "statuses", "schema": {"description": "Filter by service order line status (the 'Status Now' column). Repeatable / comma-separated. Allowed: NOT_STARTED, IN_PROGRESS, FIELD_COMPLETED, COMPLETED, CANCELLED.", "items": {"type": "string"}, "title": "Statuses", "type": "array"}, "required": false, "description": "Filter by service order line status (the 'Status Now' column). Repeatable / comma-separated. Allowed: NOT_STARTED, IN_PROGRESS, FIELD_COMPLETED, COMPLETED, CANCELLED."}, {"in": "query", "name": "date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Activity date", "title": "Date"}, "required": false, "description": "Activity date"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field (snake_case). Prefix with '-' for descending. Supported: id, service_code, actual_status, report_status, customer_name, project_code, turbine_name, location_name, activity_from, activity_to, daily_report_last_sent_at.", "title": "Sort"}, "required": false, "description": "Sort field (snake_case). Prefix with '-' for descending. Supported: id, service_code, actual_status, report_status, customer_name, project_code, turbine_name, location_name, activity_from, activity_to, daily_report_last_sent_at."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DailyReportSolResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Return SOLs matching the daily-report filters for the preview table.", "tags": ["technician.reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/download": {"post": {"operationId": "reports_api_download_report", "summary": "Download Report", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Generate and download a daily report via the reporting engine.", "tags": ["technician.reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DownloadReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/submit-draft": {"post": {"operationId": "reports_api_submit_draft_report", "summary": "Submit Draft Report", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendReportResponse"}}}}}, "description": "Submit a daily report draft (log + PM email) without file download response.", "tags": ["technician.reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DownloadReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/send": {"post": {"operationId": "reports_api_send_report", "summary": "Send Report", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendReportResponse"}}}}}, "description": "Send a daily report via the reporting engine send endpoint.\n\nTechnicians cannot call this endpoint \u2014 on the Daily Reports page they\nuse /reports/submit-draft to notify the PM instead of sending to the\nclient. Customer delivery stays with PMs and admins.\n\nWhen file_token and report_token are supplied (from the download step),\nthe reporting engine attaches the already-rendered file without re-rendering.\nWhen omitted, the report is generated fresh before sending.\n\nRecipients are resolved here, not by the reporting engine: OpsHub owns the\nPre-job \"Would you like to receive daily reports?\" answer and the Pre-job \u2192\nRFI recipient fallback, and passes the finished list to the engine. A\nproject that answered \"no\" is refused outright.", "tags": ["technician.reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/download": {"post": {"operationId": "reports_api_download_final_report", "summary": "Download Final Report", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Generate and download a final report for a single service order line.", "tags": ["technician.reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/send": {"post": {"operationId": "reports_api_send_final_report", "summary": "Send Final Report", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendReportResponse"}}}}}, "description": "Render a final report and send it via the reporting engine.\n\nRecipients are resolved here, not by the engine, mirroring the daily\n``send_report``: the Pre-job ``FINAL_REPORT`` selection with the RFI\nfallback plus internal copies. Resolved before the render so a project\nwith nobody to send to is refused without a wasted render.", "tags": ["technician.reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/start": {"post": {"operationId": "reports_api_start_final_report", "summary": "Start Final Report", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportStartResponse"}}}}}, "description": "Kick off async final-report generation; returns immediately with a token.", "tags": ["technician.reports"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/{generation_id}/status": {"get": {"operationId": "reports_api_final_report_status", "summary": "Final Report Status", "parameters": [{"in": "path", "name": "generation_id", "schema": {"title": "Generation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportStatusResponse"}}}}}, "description": "Poll the status of an in-flight final-report generation.", "tags": ["technician.reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/{generation_id}/download": {"get": {"operationId": "reports_api_download_final_report_by_id", "summary": "Download Final Report By Id", "parameters": [{"in": "path", "name": "generation_id", "schema": {"title": "Generation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download the stored PDF for a generation (fresh or previously generated).\n\nAlways serves our own copy \u2014 the PDF is persisted to the file store when\ngeneration completes, so downloads never touch the reporting engine.", "tags": ["technician.reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/state": {"get": {"operationId": "reports_api_final_report_state", "summary": "Final Report State", "parameters": [{"in": "query", "name": "service_order_line_id", "schema": {"description": "Service order line ID", "title": "Service Order Line Id", "type": "integer"}, "required": true, "description": "Service order line ID"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FinalReportStateResponse"}}}}}, "description": "Return the latest completed + any in-flight generation for the modal.", "tags": ["technician.reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/technician/reports/final-report/{generation_id}/send": {"post": {"operationId": "reports_api_send_final_report_by_id", "summary": "Send Final Report By Id", "parameters": [{"in": "path", "name": "generation_id", "schema": {"title": "Generation Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendReportResponse"}}}}}, "description": "Email a previously generated final report, reusing its rendered snapshot.\n\nRecipients come from ``_resolve_final_report_recipient_emails`` (Pre-job\n``FINAL_REPORT`` selection, RFI fallback, internal copies, archive and\nforwards), never from the engine's own lookup. The engine send needs the\nfile token, which is fetched lazily when the report was never downloaded\nin this session.", "tags": ["technician.reports"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/services": {"get": {"operationId": "dispatch_api_services_list_services", "summary": "List Services", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DispatchService"}, "title": "Response", "type": "array"}}}}}, "description": "List all services.\n\nTODO: Services needs testing to be properly used.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/services/{service_id}": {"get": {"operationId": "dispatch_api_services_get_service", "summary": "Get Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DispatchService"}}}}}, "description": "Retrieve a service.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-items": {"get": {"operationId": "dispatch_api_services_list_service_items", "summary": "List Service Items", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "is_optional", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceItem"}, "title": "Response", "type": "array"}}}}}, "description": "List service items.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-items/{service_item_id}": {"get": {"operationId": "dispatch_api_services_get_service_item", "summary": "Get Service Item", "parameters": [{"in": "path", "name": "service_item_id", "schema": {"title": "Service Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceItem"}}}}}, "description": "Retrieve a service item.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/services/{service_id}/service-items": {"get": {"operationId": "dispatch_api_services_list_service_items_for_service", "summary": "List Service Items For Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "is_optional", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceItem"}, "title": "Response", "type": "array"}}}}}, "description": "List service items for a service.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/services/{service_id}/service-items/{service_item_id}": {"get": {"operationId": "dispatch_api_services_get_service_item_for_service", "summary": "Get Service Item For Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_item_id", "schema": {"title": "Service Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceItem"}}}}}, "description": "Retrieve a service item for a service.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-item-activities": {"get": {"operationId": "dispatch_api_services_list_service_item_activities", "summary": "List Service Item Activities", "parameters": [{"in": "query", "name": "service_item_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Id"}, "required": false}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceItemActivity"}, "title": "Response", "type": "array"}}}}}, "description": "List service item activities.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-item-activities/{activity_id}": {"get": {"operationId": "dispatch_api_services_get_service_item_activity", "summary": "Get Service Item Activity", "parameters": [{"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceItemActivity"}}}}}, "description": "Retrieve a service item activity.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/services/{service_id}/service-items/{service_item_id}/activities": {"get": {"operationId": "dispatch_api_services_list_service_item_activities_for_service", "summary": "List Service Item Activities For Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_item_id", "schema": {"title": "Service Item Id", "type": "integer"}, "required": true}, {"in": "query", "name": "service_item_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Id"}, "required": false}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceItemActivity"}, "title": "Response", "type": "array"}}}}}, "description": "List service item activities for a service item.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/services/{service_id}/service-items/{service_item_id}/activities/{activity_id}": {"get": {"operationId": "dispatch_api_services_get_service_item_activity_for_service", "summary": "Get Service Item Activity For Service", "parameters": [{"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_item_id", "schema": {"title": "Service Item Id", "type": "integer"}, "required": true}, {"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceItemActivity"}}}}}, "description": "Retrieve a service item activity for a service item.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-orders": {"get": {"operationId": "dispatch_api_services_list_service_orders", "summary": "List Service Orders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "required": false}, {"in": "query", "name": "windpark_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceOrderHeader"}, "title": "Response", "type": "array"}}}}}, "description": "List service orders.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_services_create_service_order", "summary": "Create Service Order", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderHeader"}}}}}, "description": "Create a service order.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderHeaderInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-orders/summary": {"get": {"operationId": "dispatch_api_services_get_service_order_summary", "summary": "Get Service Order Summary", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderSummary"}}}}}, "description": "Summarize service orders.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-orders/{service_order_id}": {"get": {"operationId": "dispatch_api_services_get_service_order", "summary": "Get Service Order", "parameters": [{"in": "path", "name": "service_order_id", "schema": {"title": "Service Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderHeader"}}}}}, "description": "Retrieve a service order.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_services_patch_service_order", "summary": "Patch Service Order", "parameters": [{"in": "path", "name": "service_order_id", "schema": {"title": "Service Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderHeader"}}}}}, "description": "Partially update a service order.\n\nTODO: this is not yet fully implemented. Needs tests.", "tags": ["dispatch.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderHeaderInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_services_delete_service_order", "summary": "Delete Service Order", "parameters": [{"in": "path", "name": "service_order_id", "schema": {"title": "Service Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Delete a service order.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-order-lines": {"get": {"operationId": "dispatch_api_services_list_service_order_lines", "summary": "List Service Order Lines", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "project_scope_item_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Scope Item Id"}, "required": false}, {"in": "query", "name": "original_sol_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Original Sol Id"}, "required": false}, {"in": "query", "name": "billable", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Billable"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceOrderLine"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List service order lines.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_services_create_service_order_line", "summary": "Create Service Order Line", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLine"}}}}}, "description": "Create a service order line.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/service-order-lines/{line_id}": {"get": {"operationId": "dispatch_api_services_get_service_order_line", "summary": "Get Service Order Line", "parameters": [{"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLine"}}}}}, "description": "Retrieve a service order line.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "dispatch_api_services_update_service_order_line", "summary": "Update Service Order Line", "parameters": [{"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLine"}}}}}, "description": "Update a service order line.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_services_patch_service_order_line", "summary": "Patch Service Order Line", "parameters": [{"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLine"}}}}}, "description": "Partially update a service order line.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_services_delete_service_order_line", "summary": "Delete Service Order Line", "parameters": [{"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Delete a service order line.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorders": {"get": {"operationId": "dispatch_api_workorders_list_workorders", "summary": "List Workorders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "required": false}, {"in": "query", "name": "windpark_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "required": false}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "required": false}, {"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "required": false}, {"in": "query", "name": "planned_start_datetime", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime"}, "required": false}, {"in": "query", "name": "planned_start_datetime__gte", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime Gte"}, "required": false}, {"in": "query", "name": "planned_start_datetime__lte", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime Lte"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Workorder"}, "title": "Response", "type": "array"}}}}}, "description": "List workorders.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_workorders_create_workorder", "summary": "Create Workorder", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Workorder"}}}}}, "description": "Create a workorder.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorders/summary": {"get": {"operationId": "dispatch_api_workorders_get_workorder_summary", "summary": "Get Workorder Summary", "parameters": [{"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderSummary"}}}}}, "description": "Summarize workorders.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorders/activity-counts": {"get": {"operationId": "dispatch_api_workorders_get_workorder_activity_counts", "summary": "Get Workorder Activity Counts", "parameters": [{"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "required": false}, {"in": "query", "name": "workorder_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workorder Ids"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityCountsResponse"}}}}}, "description": "Return workorder activity counts.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-activities": {"get": {"operationId": "dispatch_api_workorders_list_workorder_activities", "summary": "List Workorder Activities", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "required": false}, {"in": "query", "name": "service_item_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Id"}, "required": false}, {"in": "query", "name": "service_item_activity_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Activity Id"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderActivity"}, "title": "Response", "type": "array"}}}}}, "description": "List workorder activities.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_workorders_create_workorder_activity", "summary": "Create Workorder Activity", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivity"}}}}}, "description": "Create a workorder activity.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityCreateInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorders/bulk": {"post": {"operationId": "dispatch_api_workorders_bulk_create_workorders", "summary": "Bulk Create Workorders", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Workorder"}, "title": "Response", "type": "array"}}}}}, "description": "Create multiple workorders in a single transaction.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderBulkInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorders/{workorder_id}": {"get": {"operationId": "dispatch_api_workorders_get_workorder", "summary": "Get Workorder", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Workorder"}}}}}, "description": "Retrieve a workorder.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "dispatch_api_workorders_update_workorder", "summary": "Update Workorder", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Workorder"}}}}}, "description": "Update a workorder.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_workorders_patch_workorder", "summary": "Patch Workorder", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Workorder"}}}}}, "description": "Partially update a workorder.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_workorders_delete_workorder", "summary": "Delete Workorder", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a workorder (sets deleted_at via SoftDeleteMixinDeletedAt).\n\nNOTE: The admin UI no longer offers delete. Use the cancel endpoint\n(POST /workorders/{id}/cancel) instead \u2014 soft delete hides the workorder\nfrom default queries and loses visibility into why it went away, whereas\ncancel keeps the workorder addressable with status=CANCELLED, a recorded\nreason, and a status change log entry capturing the actor.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorders/{workorder_id}/cancel": {"post": {"operationId": "dispatch_api_workorders_cancel_workorder", "summary": "Cancel Workorder", "parameters": [{"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Workorder"}}}}}, "description": "Cancel a workorder with a recorded reason.\n\nSets status to CANCELLED, persists the reason on the workorder, and\nappends a row to WorkorderStatusChangeLog with reason and actor.\nReplaces the soft-delete flow on the admin UI \u2014 cancellation keeps the\nworkorder visible and audit-traceable instead of hiding it via deleted_at.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderCancelInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-activities/{activity_id}": {"get": {"operationId": "dispatch_api_workorders_get_workorder_activity", "summary": "Get Workorder Activity", "parameters": [{"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivity"}}}}}, "description": "Retrieve a workorder activity.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "dispatch_api_workorders_update_workorder_activity", "summary": "Update Workorder Activity", "parameters": [{"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivity"}}}}}, "description": "Update a workorder activity.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_workorders_patch_workorder_activity", "summary": "Patch Workorder Activity", "parameters": [{"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivity"}}}}}, "description": "Partially update a workorder activity.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_workorders_delete_workorder_activity", "summary": "Delete Workorder Activity", "parameters": [{"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Delete a workorder activity.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-activities/bulk/update": {"patch": {"operationId": "dispatch_api_workorders_bulk_patch_workorder_activities", "summary": "Bulk Patch Workorder Activities", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderActivity"}, "title": "Response", "type": "array"}}}}}, "description": "Bulk partially update workorder activities and delay teams.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityBulkUpdateInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-activities/{activity_id}/time-edits": {"get": {"operationId": "dispatch_api_workorders_list_workorder_activity_time_edits", "summary": "List Workorder Activity Time Edits", "parameters": [{"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderActivityTimeEdit"}, "title": "Response", "type": "array"}}}}}, "description": "List the start/end time edit history for a workorder activity.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-plans": {"get": {"operationId": "dispatch_api_workorders_list_workorder_plans", "summary": "List Workorder Plans", "parameters": [{"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "resource_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderPlan"}, "title": "Response", "type": "array"}}}}}, "description": "List workorder plans.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_workorders_create_workorder_plan", "summary": "Create Workorder Plan", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlan"}}}}}, "description": "Create a workorder plan.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlanInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-plans/{plan_id}": {"get": {"operationId": "dispatch_api_workorders_get_workorder_plan", "summary": "Get Workorder Plan", "parameters": [{"in": "path", "name": "plan_id", "schema": {"title": "Plan Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlan"}}}}}, "description": "Retrieve a workorder plan.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "dispatch_api_workorders_update_workorder_plan", "summary": "Update Workorder Plan", "parameters": [{"in": "path", "name": "plan_id", "schema": {"title": "Plan Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlan"}}}}}, "description": "Update a workorder plan.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlanInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_workorders_patch_workorder_plan", "summary": "Patch Workorder Plan", "parameters": [{"in": "path", "name": "plan_id", "schema": {"title": "Plan Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlan"}}}}}, "description": "Partially update a workorder plan.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderPlanInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_workorders_delete_workorder_plan", "summary": "Delete Workorder Plan", "parameters": [{"in": "path", "name": "plan_id", "schema": {"title": "Plan Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Delete a workorder plan.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/work-time-logs": {"get": {"operationId": "dispatch_api_workorders_list_work_time_logs", "summary": "List Work Time Logs", "parameters": [{"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "required": false}, {"in": "query", "name": "activity_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activity Id"}, "required": false}, {"in": "query", "name": "resource_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "required": false}, {"in": "query", "name": "started_at", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "required": false}, {"in": "query", "name": "ended_at", "schema": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "required": false}, {"in": "query", "name": "work_time_category_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "robot_set_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "required": false}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkTimeLog"}, "title": "Response", "type": "array"}}}}}, "description": "List work time logs.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_workorders_create_work_time_log", "summary": "Create Work Time Log", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkTimeLog"}}}}}, "description": "Create a work time log.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkTimeLogInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/work-time-logs/{log_id}": {"get": {"operationId": "dispatch_api_workorders_get_work_time_log", "summary": "Get Work Time Log", "parameters": [{"in": "path", "name": "log_id", "schema": {"title": "Log Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkTimeLog"}}}}}, "description": "Retrieve a work time log.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_workorders_patch_work_time_log", "summary": "Patch Work Time Log", "parameters": [{"in": "path", "name": "log_id", "schema": {"title": "Log Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkTimeLog"}}}}}, "description": "Partially update a work time log.\n\nTODO: this is not yet fully implemented. Needs tests.", "tags": ["dispatch.workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkTimeLogInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_workorders_delete_work_time_log", "summary": "Delete Work Time Log", "parameters": [{"in": "path", "name": "log_id", "schema": {"title": "Log Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Delete a work time log.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-status-changes": {"get": {"operationId": "dispatch_api_workorders_list_workorder_status_changes", "summary": "List Workorder Status Changes", "parameters": [{"in": "query", "name": "workorder_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderStatusChange"}, "title": "Response", "type": "array"}}}}}, "description": "List workorder status changes.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-status-changes/{change_id}": {"get": {"operationId": "dispatch_api_workorders_get_workorder_status_change", "summary": "Get Workorder Status Change", "parameters": [{"in": "path", "name": "change_id", "schema": {"title": "Change Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderStatusChange"}}}}}, "description": "Retrieve a workorder status change.\n\nTODO: this is not yet fully implemented. Needs async conversion needs tests.", "tags": ["dispatch.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-activity-metadata": {"get": {"operationId": "dispatch_api_workorder_activity_metadata_list_workorder_activity_metadata", "summary": "List Workorder Activity Metadata", "parameters": [{"in": "query", "name": "workorder_activity_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderActivityMetadata"}, "title": "Response", "type": "array"}}}}}, "description": "List workorder activity metadata entries.", "tags": ["dispatch.workorder-activity-metadata"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "dispatch_api_workorder_activity_metadata_create_workorder_activity_metadata", "summary": "Create Workorder Activity Metadata", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityMetadata"}}}}}, "description": "Create a workorder activity metadata entry.", "tags": ["dispatch.workorder-activity-metadata"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityMetadataInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/workorder-activity-metadata/{metadata_id}": {"get": {"operationId": "dispatch_api_workorder_activity_metadata_get_workorder_activity_metadata", "summary": "Get Workorder Activity Metadata", "parameters": [{"in": "path", "name": "metadata_id", "schema": {"title": "Metadata Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityMetadata"}}}}}, "description": "Retrieve a workorder activity metadata entry.", "tags": ["dispatch.workorder-activity-metadata"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "dispatch_api_workorder_activity_metadata_patch_workorder_activity_metadata", "summary": "Patch Workorder Activity Metadata", "parameters": [{"in": "path", "name": "metadata_id", "schema": {"title": "Metadata Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityMetadata"}}}}}, "description": "Partially update a workorder activity metadata entry.", "tags": ["dispatch.workorder-activity-metadata"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderActivityMetadataPatchInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_workorder_activity_metadata_delete_workorder_activity_metadata", "summary": "Delete Workorder Activity Metadata", "parameters": [{"in": "path", "name": "metadata_id", "schema": {"title": "Metadata Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a workorder activity metadata entry.", "tags": ["dispatch.workorder-activity-metadata"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/board-data": {"get": {"operationId": "get_board_data_v1", "summary": "Get dispatching board data", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}, {"in": "query", "name": "until", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Until"}, "required": false}, {"in": "query", "name": "include_backlog", "schema": {"default": true, "title": "Include Backlog", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BoardDataResponse"}}}}}, "description": "Return all data needed for the dispatching board.\n\nAggregates:\n- Project resource sets with their members\n- All project workorders (service + admin) with resource assignments\n- Service order lines grouped for the panel\n\nWhen both ``since`` and ``until`` are supplied, the workorders list is\nfiltered to a date window \u2014 useful for the dispatching console where\nonly the relevant working set should be returned. The five filter\nclauses are: scheduled in window, mandatory in window,\nassigned-but-unscheduled, due-dated backlog within\n``dispatch.managers.board_reads.BACKLOG_HORIZON_DAYS``, and unassigned\nWOs from PLANNING/EXECUTION projects (regardless of due date). Without\nthe params, the legacy behaviour is preserved (returns all non-cancelled\nworkorders).\n\nThe windowed result also folds in real work that was logged but never\nformally dispatched (DISP-4368, see\n``dispatch.managers.logged_unplanned._get_logged_unplanned_workorders``)\n-- those rows carry ``is_logged_unplanned=True`` with a planned window\nderived from the actual logged activity times, and are dropped entirely\nif that derived window clashes with a genuinely planned entry for one of\nthe same resources.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/board-turbines": {"get": {"operationId": "get_board_turbines_v1", "summary": "Get per-turbine status rollup for the dispatching board", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BoardTurbinesResponse"}}}}}, "description": "Per-turbine status + activity-group completion for the whole project,\nregardless of the board's date window (see\n``dispatch.managers.board_reads._get_project_turbines``).\n\nKept on its own query, decoupled from ``board-data``'s per-mutation\nrefetch cycle, since this scan covers every non-cancelled workorder in\nthe project and dominates payload size.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/backlog": {"get": {"operationId": "get_backlog_v1", "summary": "Server-filtered, paginated work-order list for the dispatch sidebar", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "assignment", "schema": {"default": "open", "title": "Assignment", "type": "string"}, "required": false}, {"in": "query", "name": "statuses", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Statuses"}, "required": false}, {"in": "query", "name": "kinds", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Kinds"}, "required": false}, {"in": "query", "name": "service_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Codes"}, "required": false}, {"in": "query", "name": "turbine_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Ids"}, "required": false}, {"in": "query", "name": "logged_unplanned", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Logged Unplanned"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 300, "title": "Page Size", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BacklogPageResponse"}}}}}, "description": "Sidebar work-order list with server-side filtering and pagination.\n\nA large project can hold thousands of unassigned workorders \u2014 shipping\nthem all inside ``board-data`` made the board slow and the browser\nunstable, so the sidebar reads this endpoint instead (and ``board-data``\nis called with ``include_backlog=false``).\n\nFilters: ``q`` full-text-ish search (name, description, service code,\nturbine name, SO number); ``assignment`` open|unassigned|assigned, where\n``assigned`` means an active resource-set link EXISTS, ``unassigned`` means\nnone does, and ``open`` (the default, what the sidebar shows) is\nunassigned work PLUS any ``IN_PROGRESS`` workorder regardless of its team\nlink -- running work that was dispatched earlier still has to be found\nand moved to the next day when it does not finish, and it normally still\ncarries its team; ``statuses``/``kinds``/``service_codes`` as\ncomma-separated lists; ``logged_unplanned`` narrows to (``true``) or\nexcludes (``false``) real work logged with no formal dispatch (DISP-4368)\n-- these rows are already part of the unassigned scope and otherwise\nindistinguishable by status from any untouched backlog WO, so this is\nwhat makes them findable across a project's full backlog rather than only\non whichever board day/week they happen to be scrolled to. ``counts`` in\nthe response carries facet totals for the filter chips, each computed\nbefore its own facet filter (standard faceting), over the search +\nassignment scope.\n\nSee ``dispatch.managers.backlog._get_backlog_sync`` for the query shape:\nthe assignment counts come from one query (grouping on a ``has_team``\nannotation rather than filtering `base` twice), and the three facet\nbreakdowns (statuses/kinds/services) come from one grouped query across\nall three dimensions at once, summed per dimension in Python.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/board-weather": {"get": {"operationId": "get_board_weather_v1", "summary": "Get dispatching board weather", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "date", "schema": {"format": "date", "title": "Date", "type": "string"}, "required": true}, {"in": "query", "name": "project_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BoardWeatherResponse"}}}}}, "description": "Hourly weather forecast for a project location on ``date``.\n\nThe whole UTC day, read from the ``weather_forecast`` cache (kept warm by the scheduled Gust sync). On a\ncache miss for an in-horizon day, the location's bucket is backfilled from\nGust on the fly (one query) and re-read. Fail-soft: returns\n``available=false`` with no hours when the location has no coordinates or no\nforecast is available, so the board always renders.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/coverage": {"get": {"operationId": "dispatch_coverage_v1", "summary": "Per-project resource-set coverage by day", "parameters": [{"in": "query", "name": "since", "schema": {"format": "date", "title": "Since", "type": "string"}, "required": true}, {"in": "query", "name": "until", "schema": {"format": "date", "title": "Until", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectCoverageResponse"}, "title": "Response", "type": "array"}}}}}, "description": "For each project active in the window, return the total active resource\nsets and the per-day count of resource sets with at least one workorder\nplanned to start on that day. Coverage % is computed client-side.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/adoption": {"get": {"operationId": "dispatch_adoption_v1", "summary": "Teams x dates table of what the board dispatched (OH-4167)", "parameters": [{"in": "query", "name": "since", "schema": {"format": "date", "title": "Since", "type": "string"}, "required": true}, {"in": "query", "name": "until", "schema": {"format": "date", "title": "Until", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdoptionTableResponse"}}}}}, "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/supervisor-options": {"get": {"operationId": "list_supervisor_options_v1", "summary": "List BTO supervisors and the core projects they supervise", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SupervisorOption"}, "title": "Response", "type": "array"}}}}}, "description": "Supervisors exist only on BTO rosters (``team_members`` entries with\nrole \"Supervisor\") \u2014 there is no core-project supervisor field yet\n(OH-2774).", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/assign": {"post": {"operationId": "assign_workorder_v1", "summary": "Assign workorder to resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Assign a workorder to a resource set and set planned datetimes.\n\nFinds the ProjectResourceSet that contains the given resource_ids,\nensures a WorkorderResourceSet links the workorder to it, and sets\nWorkorder.planned_start_datetime / planned_end_datetime.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AssignWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/assign-bulk": {"post": {"operationId": "assign_workorders_bulk_v1", "summary": "Bulk assign workorders to resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Assign multiple workorders to resources and set planned datetimes.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkAssignWorkordersPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/unassign": {"post": {"operationId": "unassign_workorder_v1", "summary": "Unassign workorder from resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Remove all resource assignments and clear planned datetimes for a workorder.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UnassignWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/workorders/{workorder_id}": {"delete": {"operationId": "delete_admin_workorder_v1", "summary": "Soft-delete an administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a dispatcher-created ADMIN workorder (and its dispatch links).\n\nOnly administrative work (ADMIN/OFFICE) may be deleted from the board \u2014 field\nservice work is driven by the service order and must not be removed here.", "tags": ["dispatch.board-workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/admin-workorder/{workorder_id}": {"patch": {"operationId": "update_admin_workorder_v1", "summary": "Edit an existing administrative workorder's name/duration", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateAdminWorkorderResponse"}}}}}, "description": "DISP-2892: the drawer's edit-mode pencil icon for an ADMIN workorder.\n\nName and duration only -- assignee is fixed after creation (no endpoint\nfor it exists), and activities are edited individually via\n``update_workorder_activity`` below.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateAdminWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/workorders/{workorder_id}/turbine": {"post": {"operationId": "set_workorder_turbine_v1", "summary": "Set the turbine for a scope-dispatched workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Bind a turbine to a scope-dispatched (DISP-2259) workorder + its SOL,\nonce the crew knows which asset they're actually working on. No-op if\nalready set to the same turbine; rejects overwriting a different one.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetWorkorderTurbinePayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/admin-workorder": {"post": {"operationId": "create_admin_workorder_v1", "summary": "Create an ADMIN workorder assigned to a single technician", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateAdminWorkorderResponse"}}}}}, "description": "Create a standalone ADMIN workorder pinned to one individual technician.\n\nThe workorder is scoped to ``project_id`` and inherits the project's\n``requesting_customer`` (so it is visible under the customer-scoped RLS\npolicy and returned by ``board-data``). It is created with\n``type=ADMIN`` / ``status=NOT_STARTED`` via the canonical\n``WorkorderManager.gql_create`` path, then linked to the project resource\nset the technician belongs to and pinned to that individual \u2014 reusing the\nsame assignment machinery as ``/assign`` so the board routes it into the\nmember's person lane.\n\nThe manager creates, links, and pins the workorder inside one\ntransaction: if the resource-set or assignee step fails, the workorder\nmust not be left committed without its dispatch links (mirrors the\natomic pattern in ``_assign_workorders_bulk_sync``).", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateAdminWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/workorders/{workorder_id}/activities": {"post": {"operationId": "add_workorder_activity_v1", "summary": "Add an activity to an existing administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddWorkorderActivityResponse"}}}}}, "description": "Add one WorkorderActivity to an already-created ADMIN workorder\n(DISP-2379) -- lets a dispatcher extend scope after creation, the same\nway activities picked at create time work.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminActivityInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/workorders/{workorder_id}/activities/{activity_id}": {"patch": {"operationId": "update_workorder_activity_v1", "summary": "Edit an activity on an existing administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}, {"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateWorkorderActivityResponse"}}}}}, "description": "DISP-2892: the drawer's edit-mode counterpart to\n``add_workorder_activity`` -- same remaining-budget rule, but excluding\nthis activity's own current duration from the \"other activities\" total.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateWorkorderActivityPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_workorder_activity_v1", "summary": "Remove an activity from an existing administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}, {"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete one WorkorderActivity from an ADMIN workorder (FEAT-2554\nfollow-up) -- the undo of ``add_workorder_activity`` above.\n\nRefuses to remove the workorder's last remaining activity: that would\nrecreate the exact \"inert on mobile\" state DISP-2379 exists to prevent.", "tags": ["dispatch.board-workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/scope-groups": {"get": {"operationId": "list_scope_groups_v1", "summary": "List service/component-type buckets of scope items available for team dispatch", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScopeGroupResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Group real per-turbine scope items by (service, component_type) --\nsee ``list_scope_groups_sync``.", "tags": ["dispatch.scope-commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/scope-workorder": {"post": {"operationId": "create_scope_workorder_v1", "summary": "Reserve pending scope-dispatch commitments for a team against a scope bucket", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateScopeWorkorderResponse"}}}}}, "description": "Dispatch a team against a scope bucket -- no turbine pinned yet.", "tags": ["dispatch.scope-commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateScopeWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/scope-commitments/{commitment_id}/turbines": {"get": {"operationId": "list_scope_commitment_turbine_options_v1", "summary": "List turbines a pending scope-dispatch commitment can resolve to", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScopeCommitmentTurbineOption"}, "title": "Response", "type": "array"}}}}}, "description": "Turbines with at least one free (not actively dispatched) scope row in\nthis commitment's bucket \u2014 the drawer's picker offers ONLY these, so a\ndispatcher can't pick a turbine that is out of scope or already claimed.\n\nShared with the GraphQL ``scopeCommitmentTurbineOptions`` query instead of\nduplicating the filter -- see ``list_scope_commitment_turbine_options_sync``.", "tags": ["dispatch.scope-commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/scope-commitments/{commitment_id}/turbine": {"post": {"operationId": "resolve_scope_commitment_turbine_v1", "summary": "Resolve a pending scope-dispatch commitment by picking a turbine", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "OpsHub fallback for AeroTask's resolveScopeCommitmentTurbine.", "tags": ["dispatch.scope-commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveScopeCommitmentPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/scope-commitments/{commitment_id}": {"patch": {"operationId": "reschedule_scope_commitment_v1", "summary": "Reschedule a still-pending scope-dispatch commitment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Move a still-PENDING commitment's planned window, and optionally its\nteam -- see ``reschedule_scope_commitment_sync``.", "tags": ["dispatch.scope-commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RescheduleScopeCommitmentPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "cancel_scope_commitment_v1", "summary": "Cancel a still-pending scope-dispatch commitment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a still-PENDING commitment, freeing its capacity.", "tags": ["dispatch.scope-commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/day-commentary": {"post": {"operationId": "create_day_commentary_v1", "summary": "Add a dispatcher's day-commentary note to a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DayCommentaryResponse"}}}}}, "description": "Record a free-form dispatcher note about one day on a project\n(DISP-2285). Internal-only: no GraphQL field exposes this, so it never\nreaches AeroTask.", "tags": ["dispatch.board-annotations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DayCommentaryPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "list_day_commentary_v1", "summary": "List a project's day-commentary notes for one day", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "date", "schema": {"format": "date", "title": "Date", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DayCommentaryResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/service-kpis": {"get": {"operationId": "list_service_kpis_v1", "summary": "List KPI (benchmark duration) settings for every service used on a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceKpiResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Every service this project's scope references, with its effective KPI\nduration -- this project's own override (DISP-2988) if one is set, else\nthe flat `Service.default_kpi_minutes` (DISP-2925). Feeds the board's\n\"Service KPIs\" settings pane.", "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/service-kpis/{service_id}": {"put": {"operationId": "set_service_kpi_v1", "summary": "Set a project's KPI override for one service", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceKpiResponse"}}}}}, "description": "Set (or replace) this project's KPI duration override for a service\n(DISP-2988) -- the value the dispatching board uses instead of the flat\n`Service.default_kpi_minutes` for every scope-based dispatch of this\nservice on this project.", "tags": ["dispatch.board-annotations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetServiceKpiPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_service_kpi_v1", "summary": "Clear a project's KPI override for one service, reverting to the global default", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceKpiResponse"}}}}}, "description": "Remove this project's KPI override for a service (DISP-2988), reverting\nthe board back to `Service.default_kpi_minutes` (or a `ServiceComponent`\noverride, if one applies to the bucket).", "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/dispatch/v1/projects/{project_id}/dispatch/team-messages": {"post": {"operationId": "create_team_message_v1", "summary": "Send a dispatcher message to a team", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamMessageResponse"}}}}}, "description": "Create a dated free-form note from the dispatcher to one team\n(DISP-2288). Answered once from AeroTask via the ``respondToTeamMessage``\nGraphQL mutation -- this endpoint only creates the message.", "tags": ["dispatch.board-annotations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateTeamMessagePayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "list_team_messages_v1", "summary": "List dispatcher messages to teams for a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TeamMessageResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Team messages for the project, oldest first (DISP-2288).", "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/platform/clients": {"get": {"operationId": "adminplatform_api_get_clients", "summary": "Get Clients", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlatformClients"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return list of clients from Platform.", "tags": ["platform"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/platform/daily-reports/{project_id}": {"get": {"operationId": "adminplatform_api_get_daily_reports", "summary": "Get Daily Reports", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "required": false}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "End Date"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyReportsResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get daily reports for a project.", "tags": ["platform"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects": {"get": {"operationId": "projects_api_core_get_projects", "summary": "Get Projects", "parameters": [{"in": "query", "name": "code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "not_null", "description": "Filter by code: 'all' to show all projects, 'not_null' to show only projects with code", "title": "Code"}, "required": false, "description": "Filter by code: 'all' to show all projects, 'not_null' to show only projects with code"}, {"in": "query", "name": "hasBuilderId", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "default": true, "title": "Hasbuilderid"}, "required": false}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search projects by code", "title": "Search"}, "required": false, "description": "Search projects by code"}, {"in": "query", "name": "filter[name]", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Exact project title filter", "title": "Filter[Name]"}, "required": false, "description": "Exact project title filter"}, {"in": "query", "name": "filter[name][like]", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Case-insensitive partial project title filter", "title": "Filter[Name][Like]"}, "required": false, "description": "Case-insensitive partial project title filter"}, {"in": "query", "name": "page", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1, "title": "Page"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1000, "title": "Page Size"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectList"}, "title": "Response", "type": "array"}}}}}, "description": "Retrieve projects.\n\nProjects are sourced from Pipedrive deals and from core projects. By default\n(hasBuilderId omitted) only projects that have a builder ID are returned, so\nPipedrive deals not yet linked to a project are excluded; pass hasBuilderId=false\nto list only projects without a builder ID. By default, if code is not provided\n'not_null' projects are fetched.\n\nQuery Parameters:\n code: Optional[str] - Filter by code: 'all' to show all projects, 'not_null' to show only projects with code. This parameter is mutually exclusive with status.\n hasBuilderId: Optional[bool] - Filter by builder ID (default: true): true to show only projects with builder ID, false to show only projects without builder ID\n filter[name]: Optional[str] - Filter by exact project title (case-insensitive)\n filter[name][like]: Optional[str] - Filter by partial project title (case-insensitive)\n page: Optional[int] - Page number for pagination (default: 1)\n page_size: Optional[int] - Number of items per page (default: 100)\n status: Optional[str] - Filter by status (Not Started, In RFI, Price Calculation)", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_core_create_project", "summary": "Create Project", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Project"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a project with dual-write to Core tables.\n\nTwo paths:\n1. Pipedrive path (origin_id provided) \u2014 fetches deal from Pipedrive, creates\n legacy + core records.\n2. Platform path (origin_id is None, code provided) \u2014 links an existing core\n project to a new legacy record.", "tags": ["projects.core"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}": {"get": {"operationId": "projects_api_core_get_project", "summary": "Get Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Project"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve project by id.", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-codes": {"get": {"operationId": "projects_api_core_get_project_service_codes", "summary": "Get Project Service Codes", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectServiceCode"}, "title": "Response", "type": "array"}}}}}, "description": "Return flat list of service codes with group and unit type context.", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/password": {"get": {"operationId": "projects_api_core_get_project_password", "summary": "Get Project Password", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPassword"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get and decrypt project password.", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_core_create_project_password", "summary": "Create Project Password", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectPassword"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create/regenerate password, encrypt it, delete tokens, return original password.", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_core_delete_project_password", "summary": "Delete Project Password", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete project password and any associated PWT tokens.", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/send-email": {"post": {"operationId": "projects_api_core_send_project_email", "summary": "Send Project Email", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectEmailResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Send an email for a project.\n\nThe email subject will be {project_id}+\"SUBJECT\" and content will be {project_id}+\"CONTENT\".\nIf project has a password, it will be included in the email content.\nUses SMTP to send the email.\n\nArgs:\n request: The HTTP request object\n project_id: The project ID from URL path to include in the email\n body: The email request body containing recipient email\n\nRaises:\n GenericError: If project has no password or if email sending fails", "tags": ["projects.core"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectEmailRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/user-status": {"put": {"operationId": "projects_api_core_update_project_user_status", "summary": "Update Project User Status", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Project"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update the user_status of a project; ``Cancelled`` requires a reason.", "tags": ["projects.core"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UserStatusPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_core_delete_project_user_status", "summary": "Delete Project User Status", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Project"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete the user_status of a project (sets it to None).", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/customers": {"get": {"operationId": "projects_api_core_get_customer_for_project", "summary": "Get Customer For Project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Customer"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get customers for project based on project's currency.", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/related": {"get": {"operationId": "projects_api_core_get_related_projects", "summary": "Get Related Projects", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "match", "schema": {"anyOf": [{"maximum": 100, "minimum": 1, "type": "integer"}, {"type": "null"}], "default": 60, "description": "Minimum fuzzy match score percentage (1-100, default 60)", "title": "Match"}, "required": false, "description": "Minimum fuzzy match score percentage (1-100, default 60)"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RelatedProjectsResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get related projects for a project by client/company name.\n\nRelated projects are projects that share similar client/company names using fuzzy matching.\nReturns project code, id, client name and match score for each related project, ordered by project code.\n\nQuery Parameters:\n match: Optional[int] - Minimum fuzzy match score percentage (1-100, default 60)", "tags": ["projects.core"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/general": {"put": {"operationId": "projects_api_rfi_create_project_general", "summary": "Create Project General", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRFIGeneralEdit"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a project general.", "tags": ["projects.rfi"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRFIGeneral"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_rfi_get_project_general", "summary": "Get Project General", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRFIGeneral"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve project general.", "tags": ["projects.rfi"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/billing": {"put": {"operationId": "projects_api_rfi_create_project_billing", "summary": "Create Project Billing", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBilling"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a project billing.", "tags": ["projects.rfi"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingEdit"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_rfi_get_project_billing", "summary": "Get Project Billing", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBilling"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve project billing.", "tags": ["projects.rfi"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/billing-prefilled": {"get": {"operationId": "projects_api_rfi_get_project_billing_prefilled", "summary": "Get Project Billing Prefilled", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "reference", "schema": {"description": "Project id that will be used for prefilling data", "title": "Reference", "type": "string"}, "required": true, "description": "Project id that will be used for prefilling data"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBillingPrefilled"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get prefill data for a billing.", "tags": ["projects.rfi"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/sites": {"put": {"operationId": "projects_api_rfi_create_project_site", "summary": "Create Project Site", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectSites"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update sites object in project.\n\nWhole object is a manifestation of sites in project. This is not partial update.\nEach site in the array must have site_id, if it references some existing\nsite, otherwise it is considered a new site creation.", "tags": ["projects.rfi"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectSitesEdit"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_rfi_get_project_site", "summary": "Get Project Site", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectSites"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve project site.", "tags": ["projects.rfi"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/site-safety": {"put": {"operationId": "projects_api_rfi_create_project_site_access", "summary": "Create Project Site Access", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectSiteAccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update a project safety features.", "tags": ["projects.rfi"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectSiteAccessEdit"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_rfi_get_project_site_access", "summary": "Get Project Site Access", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectSiteAccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve project safety features.", "tags": ["projects.rfi"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/assets-services": {"put": {"operationId": "projects_api_rfi_create_project_assets", "summary": "Create Project Assets", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetGroup"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Add assets and their respective services on a project.\n\nAsset groups must contain complete asset group data, any asset group that is missing\nin the new request body, will be automatically deleted.\n\nAny asset group without it's `group_id` will be considered a new asset group.\n\nTo edit specific asset group `group_id` is mandatory.", "tags": ["projects.rfi"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetGroupEdit"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_rfi_get_project_assets", "summary": "Get Project Assets", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetGroup"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve all asset groups assigned to single project.\n\nAsset groups contain assets that can consist of either collection of turbines or\nblades.\n\nAsset groups also define what services will be attached to each of this group.", "tags": ["projects.rfi"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rfi/assets-services/table-prefilled": {"get": {"operationId": "projects_api_rfi_get_project_assets_prefilled", "summary": "Get Project Assets Prefilled", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "reference", "schema": {"description": "Project id that will be used for prefilling data", "title": "Reference", "type": "string"}, "required": true, "description": "Project id that will be used for prefilling data"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetGroupPrefilled"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get prefill data for asset groups.", "tags": ["projects.rfi"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/pre-job/assets-services/table": {"get": {"operationId": "projects_api_prejob_get_project_assets_table", "summary": "Get Project Assets Table", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetTableResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get assets table data for a project.\n\nTable is full representation of all assets in the project that have been created\nin RFI stage.", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_prejob_export_project_assets_table_to_excel", "summary": "Export Project Assets Table To Excel", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Generate and return assets table data for a project as an Excel file.", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "projects_api_prejob_put_project_asset", "summary": "Put Project Asset", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetTableResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a new WTG asset in the project table that will be used only for unassigned blades.\n\nRequired fields:\n- asset_id: Display name/identifier of the WTG\n- category: Asset category code\n- latitude: Latitude coordinate\n- longitude: Longitude coordinate\n- manufacturer: WTG manufacturer\n- model: WTG model\n- service_code: Service code for this WTG\n- site: Site name\n\nFixed values that will be automatically set:\n- asset_type: Always set to 'WTG'\n- must_have_parent: Always set to False\n- parent: Always set to None\n- protected: Always set to False\n- special_blade_group_count: Always set to None\n- id: Auto-generated by database", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/pre-job/assets-services/table-upload": {"post": {"operationId": "projects_api_prejob_upload_project_assets_table", "summary": "Upload Project Assets Table", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageWithSuccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Upload Excel file with asset data.\n\nIf the Excel file has specific headers (id, asset_id, pad_id, asset_type,\nparent, latitude, longitude) in the first row (A1:G1), it bypasses the AI\nand directly updates corresponding database fields (asset_id, pad_id,\nlatitude, longitude) based on the provided 'id'.\nOtherwise, returns an error message indicating which columns are missing.", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/pre-job/assets-services/table/{db_id}": {"patch": {"operationId": "projects_api_prejob_patch_project_asset", "summary": "Patch Project Asset", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "db_id", "schema": {"title": "Db Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetTableResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update specific fields of one or multiple ProjectAssets.\n\nThis endpoint allows updating the following fields:\n- asset_id\n- parent (parent db id)\n- latitude\n- longitude\n\nOnly the fields provided in the request will be updated.\nOther fields will remain unchanged.\n\nThe db_id parameter can be a single ID or multiple comma-separated IDs.\nWhen multiple IDs are provided, the same update will be applied to all assets.", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetPatch"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_prejob_delete_project_asset", "summary": "Delete Project Asset", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "db_id", "schema": {"title": "Db Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetTableResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a project asset.\n\nThis endpoint allows deleting non-protected assets from the project table.\nProtected assets (like WTGs and their blades created from asset groups) cannot be deleted.\nOnly manually created assets (like WTGs for unassigned blades) can be deleted.\n\nArgs:\n project_id: Project ID\n db_id: Database ID of the asset to delete\n\nReturns:\n Updated assets table\n\nRaises:\n APIError: If asset is protected or not found", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/pre-job/assets-services/customer-files": {"post": {"operationId": "projects_api_prejob_associate_customer_asset_files", "summary": "Associate Customer Asset Files", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Associate customer-uploaded asset files with the project.\n\nTakes storage IDs from files uploaded via POST /files endpoint\nand associates them with the project for manual processing.", "tags": ["projects.pre-job.assets-services"], "deprecated": true, "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAssetFiles"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_prejob_get_customer_asset_files", "summary": "Get Customer Asset Files", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CustomerAssetFilesList"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all customer-uploaded asset files associated with the project.", "tags": ["projects.pre-job.assets-services"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/pre-job/pdf": {"get": {"operationId": "projects_api_prejob_get_project_pre_job_pdf", "summary": "Get Project Pre Job Pdf", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Generate and download pre-job PDF report.\n\nArgs:\n request: The HTTP request\n project_id: The project ID\n\nReturns:\n HttpResponse: PDF file download response", "tags": ["projects.pre-job"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/pre-job/assets-services/table-autofill": {"post": {"operationId": "projects_api_prejob_autofill_blade_names", "summary": "Autofill Blade Names", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectAssetTableResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Auto-fill blade names for WTGs that have exactly 3 blade children.\n\nFor each WTG that has exactly 3 blade children, this endpoint will name the blades:\n- Blade A\n- Blade B\n- Blade C\n\nOnly blades without existing names will be updated.", "tags": ["projects.pre-job.assets-services.table"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer": {"get": {"operationId": "projects_api_offer_get_project_offer", "summary": "Get Project Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOffer"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get the current offer.\n\nCurrent offer may be either a draft version or latest approved version. Latest\napproved version would be returned only if there is no draft. There can never be\nmore than one draft version.\n\nFor moving offer to approve or reject stage there must be a draft offer. One sends\nfirst the draft offer for approval and then approves or rejects it.\n\nIf draft version was approved, to make new changes to the offer new draft must be\ncreated.", "tags": ["projects.offer"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_offer_update_offer", "summary": "Update Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Set margins and quoted crew / duration on the current draft offer.\n\nSets the values without changing the offer status, so they can be populated\nat deal-create time (e.g. by sales-form) rather than only when sending for\napproval. Fields left out of the payload are untouched.", "tags": ["projects.offer"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/OfferUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/view/{version}": {"get": {"operationId": "projects_api_offer_get_offer_version", "summary": "Get Offer Version", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "version", "schema": {"title": "Version", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOffer"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a specific offer version for viewing.\n\nReturns the complete offer data for a specific version, including all line items\nwith the same format as the current offer endpoint. This allows displaying\nhistorical versions with the same UI components.", "tags": ["projects.offer.changelog"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/compare": {"get": {"operationId": "projects_api_offer_compare_offer_versions", "summary": "Compare Offer Versions", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "version1", "schema": {"title": "Version1", "type": "integer"}, "required": true}, {"in": "query", "name": "version2", "schema": {"title": "Version2", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OfferComparison"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Compare two offer versions and return detailed differences.", "tags": ["projects.offer.changelog"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/send-for-approval": {"post": {"operationId": "projects_api_offer_send_for_approval", "summary": "Send For Approval", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Send the current draft offer as a new version for review with enhanced approval routing.\n\nOnly one draft version exists and as soon as it is sent for approval new draft\nversion must be created from scratch.\n\nDuring the review process, offer version is in status `Pending` and project has\noffer_status in `Pending` state. This means that the offer is not yet reviewed.\n\nThe system automatically determines the required approver based on deal value:\n- 0-100k: Sales Director approval required\n- 100k+: CCO approval required\n\nAfter the review is completed, the offer version can be either approved or rejected.", "tags": ["projects.offer.changelog"], "requestBody": {"content": {"application/json": {"schema": {"allOf": [{"$ref": "#/components/schemas/OfferApprovalRequest"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/approve": {"post": {"operationId": "projects_api_offer_approve_offer", "summary": "Approve Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Approve the current pending offer with role-based authority check.\n\nThis endpoint approves the current pending offer, which is in status `Pending`.\nThe system checks if the user has appropriate approval authority based on\nthe offer's deal value and required_approver_role field.\n\nOnce approved, the offer version is finalized and notifications are sent.\n\nAfter approval, the project offer status is set to `Approved`.", "tags": ["projects.offer.changelog"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/reject": {"post": {"operationId": "projects_api_offer_reject_offer", "summary": "Reject Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Reject the current pending offer with role-based authority check.\n\nThis endpoint rejects the current pending offer, which is in status `Pending`.\nThe system checks if the user has appropriate approval authority based on\nthe offer's deal value and required_approver_role field.\n\nAfter rejection, the project offer status is set to `Rejected`.\nThe rejected offer version remains accessible for review and comparison.", "tags": ["projects.offer.changelog"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/OfferRejectRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/draft": {"post": {"operationId": "projects_api_offer_create_draft_offer", "summary": "Create Draft Offer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a new draft offer after an approved version exists.\n\nThis endpoint creates a new draft offer version, typically used after\nan offer has been approved or rejected and new changes need to be made.", "tags": ["projects.offer.changelog"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/download-v2": {"post": {"operationId": "projects_api_offer_download_offer_v2", "summary": "Download Offer V2", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download commercial offer for a project using offerv2.\n\nThe downloaded commercial offer is delivered as a PDF file generated using the offerv2 module.\nThis version uses docx templates for generating the PDF.", "tags": ["projects.offer"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/download-v2-docx": {"post": {"operationId": "projects_api_offer_download_offer_v2_docx", "summary": "Download Offer V2 Docx", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download commercial offer for a project as DOCX using offerv2.", "tags": ["projects.offer"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/line-items": {"post": {"operationId": "projects_api_offer_create_line_item", "summary": "Create Line Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOffer"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a new commercial offer line item.", "tags": ["projects.offer"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceLineItemCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_offer_update_line_items", "summary": "Update Line Items", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOffer"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update line items in the offer.\n\nBulk updates are service-line-item only and identified by row_id.\nSupport-item code-based mutation path has been removed.", "tags": ["projects.offer"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/LineItemsUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/offer/line-items/{line_item_id}": {"patch": {"operationId": "projects_api_offer_update_line_item", "summary": "Update Line Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "line_item_id", "schema": {"title": "Line Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOffer"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update a single commercial offer line item.", "tags": ["projects.offer"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceLineItemEdit"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_offer_delete_line_item", "summary": "Delete Line Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "line_item_id", "schema": {"title": "Line Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOffer"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a single commercial offer line item.", "tags": ["projects.offer"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/bto": {"get": {"operationId": "projects_api_bto_get_project_bto_overview", "summary": "Get Project Bto Overview", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectBTO"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return basic BTO overview data assembled via manager layer.", "tags": ["projects.bto"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents": {"get": {"operationId": "projects_api_rams_list_rams_documents", "summary": "List Rams Documents", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RamsDocumentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all RAMS documents for a project.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_rams_create_rams_document", "summary": "Create Rams Document", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDocumentResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a new RAMS document.", "tags": ["projects.rams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDocumentCreateBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/set-options": {"get": {"operationId": "projects_api_rams_get_rams_set_options", "summary": "Get Rams Set Options", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsSetOptionsResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "PPRS options (by robot set) pickable for a new RAMS on this project.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}": {"get": {"operationId": "projects_api_rams_get_rams_document", "summary": "Get Rams Document", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDocumentResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a single RAMS document.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_rams_update_rams_document", "summary": "Update Rams Document", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDocumentResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Patch a RAMS document (form_data, status, comments, etc.).", "tags": ["projects.rams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDocumentUpdateBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_rams_delete_rams_document", "summary": "Delete Rams Document", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a RAMS document.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/technician-acknowledgements": {"get": {"operationId": "projects_api_rams_list_rams_technician_acknowledgements", "summary": "List Rams Technician Acknowledgements", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RamsTechAckSummary"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List the active technician acknowledgement rows for a RAMS document.\n\nActive means ``deleted_at IS NULL`` \u2014 soft-deleted rows from a prior\nround (e.g. before HSE bounced the doc back to draft) are excluded.\nThe acknowledgement page lives at one shared URL per RAMS; each\nteam member authenticates with SSO and the page identifies them\nagainst the ack rows by ID, not a per-row token.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/technician-roster": {"get": {"operationId": "projects_api_rams_get_rams_technician_roster", "summary": "Get Rams Technician Roster", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsRosterResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Current signing roster annotated with per-person acknowledgement state.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/send-to-new-technicians": {"post": {"operationId": "projects_api_rams_send_rams_to_new_technicians", "summary": "Send Rams To New Technicians", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsRosterResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Email the roster people who have no acknowledgement row yet.\n\nAdds ack rows for them only; existing signatures and the document status\nare untouched. Allowed once the doc has reached the technician stage.\n\n``body.technician_emails`` restricts the top-up to the chosen crew members;\nan omitted body tops up everyone who has not been sent the RAMS yet.", "tags": ["projects.rams"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/RamsSendSelectionBody"}, {"type": "null"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/duplicate": {"post": {"operationId": "projects_api_rams_duplicate_rams_document", "summary": "Duplicate Rams Document", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDocumentResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Duplicate a RAMS document \u2014 copies form data, resets status to draft.\n\nThe clone keeps the original's PPRSI/robot link by default (so its derived\ndates keep tracking the deployment) and can target different site(s); pass a\n``pprs_id`` to rebind it to another set. Each site may hold at most one\nactive RAMS for the (set, service). Attachments are copied too: the body\ntext referencing them (\"see attachment\") is copied, so the files have to\ntravel with it.", "tags": ["projects.rams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsDuplicateBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/rams-attachments/shared/{token}": {"get": {"operationId": "projects_api_rams_download_shared_rams_attachment", "summary": "Download Shared Rams Attachment", "parameters": [{"in": "path", "name": "token", "schema": {"title": "Token", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download one RAMS attachment from its signed share token.\n\nDeliberately unauthenticated: the reader is a customer clicking a link\ninside a RAMS PDF, so there is no session to check and the signed token is\nthe credential. It names a single attachment, cannot be forged without\n``SECRET_KEY``, and stops resolving once the attachment is deleted.", "tags": ["projects.rams"]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/attachments": {"get": {"operationId": "projects_api_rams_list_rams_attachments", "summary": "List Rams Attachments", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RamsAttachmentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List attachments for a RAMS document.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_rams_upload_rams_attachment", "summary": "Upload Rams Attachment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsAttachmentResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Upload a file attachment to a RAMS document.", "tags": ["projects.rams"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}, "uploaded_by": {"default": "", "title": "Uploaded By", "type": "string"}}, "required": ["file"], "title": "MultiPartBodyParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/attachments/{attachment_id}": {"delete": {"operationId": "projects_api_rams_delete_rams_attachment", "summary": "Delete Rams Attachment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}, {"in": "path", "name": "attachment_id", "schema": {"title": "Attachment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a RAMS attachment.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/attachments/{attachment_id}/download": {"get": {"operationId": "projects_api_rams_download_rams_attachment", "summary": "Download Rams Attachment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}, {"in": "path", "name": "attachment_id", "schema": {"title": "Attachment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download a RAMS attachment file.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/submit-to-customer": {"post": {"operationId": "projects_api_rams_submit_rams_to_customer", "summary": "Submit Rams To Customer", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsApprovalResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a RAMS approval request for manual customer review.\n\nThe FE uploads the DOCX it just generated; this endpoint converts it to\nPDF via LibreOffice and stores the PDF for the customer to download.", "tags": ["projects.rams"], "requestBody": {"content": {"multipart/form-data": {"schema": {"title": "MultiPartBodyParams", "type": "object", "properties": {"rams_document_id": {"title": "Rams Document Id", "type": "integer"}, "service_type": {"title": "Service Type", "type": "string"}, "version": {"title": "Version", "type": "string"}, "form_data_snapshot": {"title": "Form Data Snapshot", "type": "string"}, "submitted_by": {"title": "Submitted By", "type": "string"}, "docx_file": {"format": "binary", "title": "Docx File", "type": "string"}}, "required": ["rams_document_id", "service_type", "version", "form_data_snapshot", "submitted_by", "docx_file"]}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/convert-to-pdf": {"post": {"operationId": "projects_api_rams_convert_rams_docx_to_pdf", "summary": "Convert Rams Docx To Pdf", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Convert a DOCX upload to PDF and stream the PDF back.\n\nUsed by the internal download button: the FE generates a DOCX in the\nbrowser, posts it here, receives the PDF blob, and triggers a download.", "tags": ["projects.rams"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"docx_file": {"format": "binary", "title": "Docx File", "type": "string"}}, "required": ["docx_file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/{approval_id}/status": {"get": {"operationId": "projects_api_rams_get_rams_approval_status", "summary": "Get Rams Approval Status", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "approval_id", "schema": {"title": "Approval Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsStatusResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Lightweight status check for a RAMS approval request.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/{approval_id}": {"get": {"operationId": "projects_api_rams_get_rams_for_client", "summary": "Get Rams For Client", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "approval_id", "schema": {"title": "Approval Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsApprovalResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return full RAMS data for client viewing, attachments included.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/{approval_id}/respond": {"post": {"operationId": "projects_api_rams_client_respond_to_rams", "summary": "Client Respond To Rams", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "approval_id", "schema": {"title": "Approval Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsApprovalResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Client approves or rejects the RAMS.", "tags": ["projects.rams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsClientRespondBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/{approval_id}/pdf": {"get": {"operationId": "projects_api_rams_download_rams_pdf", "summary": "Download Rams Pdf", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "approval_id", "schema": {"title": "Approval Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download the RAMS PDF file.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/technician-acknowledgements/sign": {"post": {"operationId": "projects_api_rams_sign_rams_technician_acknowledgement", "summary": "Sign Rams Technician Acknowledgement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTechAckSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Authenticated team-member acknowledgement of a RAMS.\n\nThe authenticated user is matched against the doc's active ack rows\nby email (with a fallback to the user's linked Resource). If a row\nmatches, ``acknowledged_at`` is stamped on it; if this ack closes\nthe cohort the parent RAMS auto-transitions to\n``signed_by_technicians``. 404 when the user has no row on this doc.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/technician-acknowledgements/{ack_id}/mark-signed": {"post": {"operationId": "projects_api_rams_mark_rams_technician_acknowledgement_signed", "summary": "Mark Rams Technician Acknowledgement Signed", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}, {"in": "path", "name": "ack_id", "schema": {"title": "Ack Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTechAckSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "PM/HSE marks a single technician's row as signed on their behalf.\n\nFor crew who acknowledged offline (e.g. on paper). Stamps the row and,\nif it closes the cohort, auto-advances the RAMS to\n``signed_by_technicians`` \u2014 same as a self-sign.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/rams/documents/{doc_id}/technician-acknowledgements/{ack_id}/dismiss": {"post": {"operationId": "projects_api_rams_dismiss_rams_technician_acknowledgement", "summary": "Dismiss Rams Technician Acknowledgement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "doc_id", "schema": {"title": "Doc Id", "type": "integer"}, "required": true}, {"in": "path", "name": "ack_id", "schema": {"title": "Ack Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTechAckSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "PM/HSE dismisses a single unsigned acknowledgement row.\n\nThe companion rule (OH-4041) for a \"former\" crew member who was sent the\nRAMS but is no longer on the roster and will never sign \u2014 e.g. removed from a\nmanual team mid-signing. Their unsigned row would otherwise pin the doc in\n``tech_review`` forever under the enforced invariant. Soft-deletes the row\nand re-reconciles, so the doc advances to ``signed_by_technicians`` when this\nwas the last blocker. 404 when the row isn't an active unsigned row here.", "tags": ["projects.rams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/rams-templates": {"get": {"operationId": "projects_api_rams_templates_list_rams_templates", "summary": "List Rams Templates", "parameters": [{"in": "query", "name": "service_family_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Family Id"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "required": false}, {"in": "query", "name": "region_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Region Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RamsTemplateResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List RAMS templates for the HSE template admin UI.", "tags": ["projects.rams-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_rams_templates_create_rams_template", "summary": "Create Rams Template", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a new RAMS template. At least one scope dimension is required.", "tags": ["projects.rams-templates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateCreateBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/rams-templates/convert-to-pdf": {"post": {"operationId": "projects_api_rams_templates_convert_template_docx_to_pdf", "summary": "Convert Template Docx To Pdf", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Convert a template-preview DOCX upload to PDF and stream it back.", "tags": ["projects.rams-templates"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/rams-templates/resolved": {"get": {"operationId": "projects_api_rams_templates_resolve_rams_template_content", "summary": "Resolve Rams Template Content", "parameters": [{"in": "query", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}, {"in": "query", "name": "region", "schema": {"default": "", "title": "Region", "type": "string"}, "required": false}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "required": false}, {"in": "query", "name": "country_code", "schema": {"default": "", "title": "Country Code", "type": "string"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateResolvedResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Resolve the most-specific template (a service-scoped row beats the family\nrow; then customer > country > region) a PM should start a new RAMS document\nfrom. No manager gate \u2014 read-only, used at document creation. The template\nfamily comes off ``Service.service_family`` and the optional service scope is\nthe service itself \u2014 nothing is read out of the code. A service with no\nfamily is not RAMS-eligible. Accepts a country_code (the project context\ncarries the code, not the core id). The geographic region is derived from\nthat country; the RAMS `region` string is only a fallback for callers that\npass no country.", "tags": ["projects.rams-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/rams-templates/{template_id}": {"get": {"operationId": "projects_api_rams_templates_get_rams_template", "summary": "Get Rams Template", "parameters": [{"in": "path", "name": "template_id", "schema": {"title": "Template Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return a single template plus its uploaded images.\n\nNo manager gate, and soft-deleted rows still resolve: every RAMS document\nviewer (PMs included) fetches its linked template as the drift/PPE\nbaseline, which must survive HSE retiring the template. Mutations below\nstay HSE-only.", "tags": ["projects.rams-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_rams_templates_update_rams_template", "summary": "Update Rams Template", "parameters": [{"in": "path", "name": "template_id", "schema": {"title": "Template Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update template content and/or scope. The service family and the optional\nservice narrowing are immutable post-create \u2014 they identify *what* the\ntemplate is for; duplicate it to target a different one.", "tags": ["projects.rams-templates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateUpdateBody"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_rams_templates_delete_rams_template", "summary": "Delete Rams Template", "parameters": [{"in": "path", "name": "template_id", "schema": {"title": "Template Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Soft-delete a template. Existing RAMS documents are unaffected.", "tags": ["projects.rams-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/rams-templates/{template_id}/images": {"post": {"operationId": "projects_api_rams_templates_upload_rams_template_image", "summary": "Upload Rams Template Image", "parameters": [{"in": "path", "name": "template_id", "schema": {"title": "Template Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RamsTemplateImageResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Upload an HSE default image for a specific template slot.\n\nThe bytes go to GCS through the shared ``core.File`` uploader in bare mode\n(no ``FileEntityLink``) \u2014 the template-side link is this ``RamsTemplateImage``\nrow, which carries the slot/label placement metadata.", "tags": ["projects.rams-templates"], "requestBody": {"content": {"multipart/form-data": {"schema": {"title": "MultiPartBodyParams", "type": "object", "properties": {"slot": {"title": "Slot", "type": "string"}, "label": {"default": "", "title": "Label", "type": "string"}, "file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["slot", "file"]}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/rams-templates/{template_id}/images/{image_id}": {"delete": {"operationId": "projects_api_rams_templates_delete_rams_template_image", "summary": "Delete Rams Template Image", "parameters": [{"in": "path", "name": "template_id", "schema": {"title": "Template Id", "type": "integer"}, "required": true}, {"in": "path", "name": "image_id", "schema": {"title": "Image Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Soft-delete an HSE-uploaded default image.", "tags": ["projects.rams-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/weather": {"get": {"operationId": "projects_api_weather_get_weather", "summary": "Get Weather", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "year", "schema": {"title": "Year", "type": "integer"}, "required": true}, {"in": "query", "name": "month", "schema": {"title": "Month", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyWeatherListResponse"}}}}}, "description": "Get weather data for a project's site for a given month.", "tags": ["projects.weather"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/weather/refresh": {"post": {"operationId": "projects_api_weather_refresh_weather", "summary": "Refresh Weather", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "year", "schema": {"title": "Year", "type": "integer"}, "required": true}, {"in": "query", "name": "month", "schema": {"title": "Month", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyWeatherListResponse"}}}}}, "description": "Refresh weather data from external API.\n\nThis endpoint is a placeholder - weather integration is not yet implemented.", "tags": ["projects.weather"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/weather/{date_str}": {"put": {"operationId": "projects_api_weather_update_weather_value", "summary": "Update Weather Value", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "date_str", "schema": {"title": "Date Str", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyWeatherSchema"}}}}}, "description": "Update a single weather value.", "tags": ["projects.weather"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WeatherValueUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/weather/{date_str}/reset": {"post": {"operationId": "projects_api_weather_reset_weather_value", "summary": "Reset Weather Value", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "date_str", "schema": {"title": "Date Str", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyWeatherSchema"}}}}}, "description": "Reset weather values to original API values.", "tags": ["projects.weather"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WeatherResetRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/available-services": {"get": {"operationId": "projects_api_robot_sets_and_teams_get_available_services", "summary": "Get Available Services", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AvailableServicesResponse"}}}}}, "description": "Get available services from core.Service.", "tags": ["projects.robot-sets-and-teams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/available-robot-sets": {"get": {"operationId": "projects_api_robot_sets_and_teams_get_available_robot_sets", "summary": "Get Available Robot Sets", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AvailableRobotSetsResponse"}}}}}, "description": "Get available robot sets (ProjectResourceSets) for a project.", "tags": ["projects.robot-sets-and-teams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/available-resources": {"get": {"operationId": "projects_api_robot_sets_and_teams_get_available_resources", "summary": "Get Available Resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AvailableResourcesResponse"}}}}}, "description": "Get available resources (technicians) from Platform API.", "tags": ["projects.robot-sets-and-teams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/robot-sets-and-teams": {"get": {"operationId": "projects_api_robot_sets_and_teams_get_robot_sets_and_teams", "summary": "Get Robot Sets And Teams", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetsAndTeamsResponse"}}}}}, "description": "Get robot sets and teams for a project.\n\nReturns stored data immediately without waiting for Platform API.\nNames are stored when robot sets are saved.", "tags": ["projects.robot-sets-and-teams"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "projects_api_robot_sets_and_teams_update_robot_sets_and_teams", "summary": "Update Robot Sets And Teams", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetsAndTeamsResponse"}}}}}, "description": "Update robot sets and teams for a project.", "tags": ["projects.robot-sets-and-teams"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RobotSetsAndTeamsUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/overview/percentages": {"get": {"operationId": "projects_api_overview_get_project_overview_percentages", "summary": "Get Project Overview Percentages", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectOverviewPercentages"}}}}}, "description": "Get project completion percentages for various forms.\n\nThis endpoint returns completion statistics for different project forms\nincluding RFI and Pre-job forms.\n\nArgs:\n request: The request itself\n project_id: The project ID to get completion percentages for\n\nReturns:\n ProjectOverviewPercentages: Dictionary with completion percentages for various forms", "tags": ["projects.overview"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/overview/technicians": {"get": {"operationId": "projects_api_overview_get_project_overview_technicians", "summary": "Get Project Overview Technicians", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TechnicianSimple"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get technicians list for project overview.\n\nThis endpoint fetches technicians data from the Platform API\nusing the PlatformManager.\n\nArgs:\n request: The request itself\n project_id: The project ID\n\nReturns:\n List of technicians with filtered fields from the Platform API", "tags": ["projects.overview"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/platform": {"post": {"operationId": "projects_api_platform_send_project_to_platform", "summary": "Send Project To Platform", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Creates a corresponding project in Platform based on the current project's data.\n\nEndpoint will silently accept recurring requests to create the same project.", "tags": ["projects.platform"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/generate": {"post": {"operationId": "projects_api_service_orders_generate_service_orders", "summary": "\u26a0\ufe0f Generate service orders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderGenerateResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nCreate ServiceOrderHeader, ServiceOrderLine, and Workorder records\nfrom the provided scope items.\n\nThe generation logic:\n1. Groups ServiceOrderHeaders by (project_id, location_id) - reuses existing\n2. Creates one ServiceOrderLine per scope item (1:1 relationship)\n3. Creates Workorders based on ServiceItem and ProjectScopeItem configuration\n\nScope items that already have a live (non-cancelled) SOL are refused unless\n``confirm_duplicates`` is set; without it the response returns\n``requires_confirmation`` plus the offending scope items so the UI can prompt.\n\nEach scope item can specify optional service items to include,\nwhich will generate optional workorders.", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderGenerateRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-order-lines/{line_id}/workorders/generate": {"post": {"operationId": "projects_api_service_orders_generate_line_workorders", "summary": "\u26a0\ufe0f Generate line workorders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateLineWorkordersResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGenerate additional workorders for an existing ServiceOrderLine.\n\nThis endpoint allows adding additional workorders to a line after initial generation.\nDuplicates are allowed - calling this endpoint multiple times with the same\nservice_item_ids will create additional workorders.\n\nComponent selection is derived from the line's project_scope_item:\n- If scope_item.turbine_component_id is set: only that specific component\n- If scope_item.component_type_id is set: all components of that type\n- Otherwise: all components matching the service_item's component type\n\nArgs:\n project_id: The core.Project ID\n line_id: The ServiceOrderLine ID\n body: Request with service_item_ids to generate workorders for\n\nReturns:\n GenerateLineWorkordersResponse with list of created workorder IDs\n\nErrors:\n 404: Line not found or doesn't belong to project\n 400: Validation error (wrong service, invalid component scope, etc.)", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateLineWorkordersRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/generation-data": {"get": {"operationId": "projects_api_service_orders_get_service_order_generation_data", "summary": "\u26a0\ufe0f Get service order generation data", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 50, "title": "Page Size", "type": "integer"}, "required": false}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "generation_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Generation Status"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderGenerationDataResponse"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet data for service order generation UI with pagination and filtering.\n\nThe optional ``search`` parameter narrows the result list by an icontains\nmatch against either ``turbine.name`` or ``turbine_component.serial_number``\n(OR semantics). Whitespace-only values are treated as no search.\n\n``generation_status`` filters scope items by whether they already have a live\n(non-cancelled) SOL: ``generated`` keeps only those that do, ``not_generated``\nonly those that don't. Omitted/other values apply no filter.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders": {"get": {"operationId": "projects_api_service_orders_list_service_orders", "summary": "\u26a0\ufe0f List service orders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 25, "title": "Page Size", "type": "integer"}, "required": false}, {"in": "query", "name": "location", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "required": false}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "scope_change_request_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Scope Change Request Id"}, "required": false}, {"in": "query", "name": "original_sol_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Original Sol Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectServiceOrderListItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nList service orders for a project with server-side pagination and filtering.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_service_orders_delete_all_service_orders", "summary": "\u26a0\ufe0f Delete all service orders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderDeleteResponse"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nDelete all service orders for a project.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/summary": {"get": {"operationId": "projects_api_service_orders_get_service_order_summary", "summary": "\u26a0\ufe0f Get service order summary", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderSummaryResponse"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet summary data for service orders page.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}": {"get": {"operationId": "projects_api_service_orders_get_service_order_line", "summary": "\u26a0\ufe0f Get service order line detail", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineDetail"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet service order line detail, with the customer custom fields and values\nthe caller may see.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/customer-custom-field-values": {"put": {"operationId": "projects_api_service_orders_replace_service_order_line_customer_custom_field_values", "summary": "\u26a0\ufe0f Replace the customer custom field values on a service order line", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CustomerCustomValueResponse"}, "title": "Response", "type": "array"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nStore the full set of custom field values on the line and return what is\nnow stored. A refused value writes nothing.", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceOrderLineCustomerCustomFieldValuesReplace"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/warranty-work": {"post": {"operationId": "projects_api_service_orders_create_warranty_work", "summary": "\u26a0\ufe0f Create warranty-work SOL from this line", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateWarrantyWorkResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nCreate a warranty-work SOL from this service order line. The warranty\nsibling project is get-or-created on demand. The SOL mirrors the original;\nthe caller may pick the target service, opt in optional service items, and\nnarrow workorders to a subset of turbine components (component_overrides).", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateWarrantyWorkRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/workorders": {"get": {"operationId": "projects_api_service_orders_get_service_order_line_workorders", "summary": "\u26a0\ufe0f Get service order line workorders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceOrderLineWorkorder"}, "title": "Response", "type": "array"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet workorders for a service order line.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/workorders/{workorder_id}": {"get": {"operationId": "projects_api_service_orders_get_workorder_detail", "summary": "\u26a0\ufe0f Get workorder detail", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkorderDetail"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet workorder detail.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/workorders/{workorder_id}/activities": {"get": {"operationId": "projects_api_service_orders_get_workorder_activities", "summary": "\u26a0\ufe0f Get workorder activities", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkorderActivityDetail"}, "title": "Response", "type": "array"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet activities for a workorder.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/workorders/{workorder_id}/available-activities": {"get": {"operationId": "projects_api_service_orders_get_available_activities", "summary": "\u26a0\ufe0f Get available activities", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AvailableActivity"}, "title": "Response", "type": "array"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet available activities for a workorder.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/workorders": {"get": {"operationId": "projects_api_service_orders_list_project_workorders", "summary": "\u26a0\ufe0f List project workorders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 25, "title": "Page Size", "type": "integer"}, "required": false}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectWorkorderListItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nList workorders for a project with server-side pagination and filtering.", "tags": ["projects.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/workorders/{workorder_id}": {"get": {"operationId": "projects_api_service_orders_get_admin_workorder_detail", "summary": "\u26a0\ufe0f Get admin workorder detail", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminWorkorderDetail"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet admin workorder detail.", "tags": ["projects.workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/unplanned-service-items": {"get": {"operationId": "projects_api_service_orders_get_unplanned_service_items", "summary": "\u26a0\ufe0f Get unplanned service items", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/UnplannedServiceItem"}, "title": "Response", "type": "array"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nGet unplanned service items for a service order line.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/workorders/{workorder_id}": {"delete": {"operationId": "projects_api_service_orders_delete_unplanned_workorder", "summary": "\u26a0\ufe0f Delete unplanned workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeleteWorkorderResponse"}}}}}, "description": "\u26a0\ufe0f Internal OpsHub UI endpoint. Not intended for external consumption.\n\nSoft-delete an unplanned workorder that hasn't been started (Workorder\ninherits SoftDeleteMixinDeletedAt, so this sets deleted_at rather than\nremoving the row).\n\nNOTE: The admin UI no longer offers delete. Prefer the cancel endpoint\n(POST /dispatch/v1/workorders/{id}/cancel) \u2014 soft delete hides the row\nfrom default queries; cancel keeps it visible with a recorded reason and\nactor.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/workorders/{workorder_id}/status-changes": {"get": {"operationId": "projects_api_service_orders_list_status_changes", "summary": "List workorder status change log", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/StatusChangeLogEntry"}, "title": "Response", "type": "array"}}}}}, "description": "List all status change log entries for a workorder.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_service_orders_create_status_change", "summary": "Create status change log entry", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StatusChangeLogEntry"}}}}}, "description": "Create a new status change log entry.", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateStatusChangeLogRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/workorders/{workorder_id}/status-changes/{entry_id}": {"delete": {"operationId": "projects_api_service_orders_delete_status_change", "summary": "Delete status change log entry", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}, {"in": "path", "name": "entry_id", "schema": {"title": "Entry Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}}, "description": "Delete a status change log entry.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/status-changes": {"get": {"operationId": "projects_api_service_orders_list_sol_status_changes", "summary": "List SOL status change logs", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SolStatusChangeLogGroup"}, "title": "Response", "type": "array"}}}}}, "description": "List all status change log entries for all workorders in a service order line.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/line-status-changes": {"get": {"operationId": "projects_api_service_orders_list_line_status_changes", "summary": "List a service order line's own status change log", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/StatusChangeLogEntry"}, "title": "Response", "type": "array"}}}}}, "description": "Read-only: the service order line's OWN status transition log.\n\nDistinct from the workorder-grouped SOL view above \u2014 this returns the\nServiceOrderLineStatusChangeLog rows for the line itself.", "tags": ["projects.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/status-changes/bulk-create": {"post": {"operationId": "projects_api_service_orders_bulk_create_sol_status_changes", "summary": "Bulk-create status change log entries", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SolStatusChangeLogGroup"}, "title": "Response", "type": "array"}}}}}, "description": "Bulk-create status change log entries for multiple workorders in a SOL.", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkCreateStatusChangeLogRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/service-orders/lines/{line_id}/status-changes/bulk-delete": {"post": {"operationId": "projects_api_service_orders_bulk_delete_sol_status_changes", "summary": "Bulk-delete status change log entries", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_id", "schema": {"title": "Line Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}}, "description": "Bulk soft-delete status change log entries for workorders in a SOL.", "tags": ["projects.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkDeleteStatusChangeLogRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests": {"post": {"operationId": "projects_api_team_request_create_team_request", "summary": "Create Team Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Create a DRAFT TR with N slots; first slot is the lead.", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_team_request_list_team_requests", "summary": "List Team Requests", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TeamRequestResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/site-options": {"get": {"operationId": "projects_api_team_request_get_site_options", "summary": "Get Site Options", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "project_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "required": false}, {"in": "query", "name": "project_location_ids", "schema": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Project Location Ids"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SiteOptionsResponse"}}}}}, "description": "Services + cert preview for the project's commercial-offer scope.\n\nWithout any site param: every service priced on the latest offer (the\nFE create modal renders these as the Service dropdown). With sites:\nnarrows services to those ``ProjectLocation`` rows and previews the\ndeduped *union* of required certs across them. ``project_location_ids``\nis the multi-select form; ``project_location_id`` is kept for back-compat.\n\nRegistered before ``/{team_request_id}`` so the literal path segment\nwins the route match.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/set-options": {"get": {"operationId": "projects_api_team_request_get_set_options", "summary": "Get Set Options", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetOptionsResponse"}}}}}, "description": "Robot sets pickable for a new TR.\n\nRegistered before ``/{team_request_id}`` so the literal path segment\nisn't parsed as an integer id by django-ninja's route matcher.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/offer-pairs": {"get": {"operationId": "projects_api_team_request_get_team_request_offer_pairs", "summary": "Get Team Request Offer Pairs", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OfferPairsResponse"}}}}}, "description": "(Location, Service) pairs from the project's latest commercial offer.\n\nBacks the combined \"Location \u00b7 Service\" field on the TR create modal,\nmirroring the Set Request picker. Registered before ``/{team_request_id}``\nso the literal path segment wins the route match.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}": {"get": {"operationId": "projects_api_team_request_get_team_request", "summary": "Get Team Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_team_request_update_team_request", "summary": "Update Team Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Edit notes (any non-terminal status); people_count and certs (DRAFT only).", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/cert-drift": {"get": {"operationId": "projects_api_team_request_get_cert_drift", "summary": "Get Cert Drift", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertDriftResponse"}}}}}, "description": "Diff TR's required-cert snapshot vs pre-job's current set.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/apply-cert-drift": {"post": {"operationId": "projects_api_team_request_apply_cert_drift", "summary": "Apply Cert Drift", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Re-sync TR snapshot + slot certs from pre-job. DRAFT / SUBMITTED only.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/resolve-cert-token": {"post": {"operationId": "projects_api_team_request_resolve_team_request_cert_token", "summary": "Resolve Team Request Cert Token", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CertDriftResponse"}}}}}, "description": "Resolve a customer-typed cert token from pre-job: map / create / drop.\n\nDoc-control gated \u2014 same permission as send-to-planner, since both\ngovern what reaches the planner's queue with finalised requirements.", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveCertTokenPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/submit": {"post": {"operationId": "projects_api_team_request_submit_team_request", "summary": "Submit Team Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "DRAFT \u2192 SUBMITTED. Notifies Document Controllers after commit.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/send-to-planner": {"post": {"operationId": "projects_api_team_request_send_team_request_to_planner", "summary": "Send Team Request To Planner", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "SUBMITTED \u2192 SENT_TO_PLANNER. Notifies Planners + WMS after commit.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/cancel": {"post": {"operationId": "projects_api_team_request_cancel_team_request", "summary": "Cancel Team Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Any non-terminal \u2192 CANCELLED. Soft-deletes active slots. Idempotent.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/duplicate": {"post": {"operationId": "projects_api_team_request_duplicate_team_request", "summary": "Duplicate Team Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Clone TR + slots into a new DRAFT. Rejects CANCELLED source.", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/TeamRequestDuplicate"}, {"type": "null"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/notes": {"post": {"operationId": "projects_api_team_request_create_team_request_note", "summary": "Create Team Request Note", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestEventResponse"}}}}}, "description": "Append a free-form note (with optional @-mentions) to a TR's timeline.\n\nEach mentioned user (excluding the actor) is emailed via the\n``builder.team_request.note-mention`` template. Email failures are\nswallowed per-recipient so one bad address can't drop the rest of the\nbatch or fail the API call.", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestNoteCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/events": {"get": {"operationId": "projects_api_team_request_list_team_request_events", "summary": "List Team Request Events", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TeamRequestEventResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Merged timeline: status changes + activity rows, newest first.\n\nReturns a UNION'd values() queryset; ``@paginate`` does LIMIT/OFFSET +\nCOUNT(*) in Postgres. ``TeamRequestEventResponse`` reshapes each row\nvia its before-validator.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/mention-candidates": {"get": {"operationId": "projects_api_team_request_list_team_request_mention_candidates", "summary": "List Team Request Mention Candidates", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MentionCandidateListResponse"}}}}}, "description": "Users available for @-mention on a TR note.\n\nReturns every active user. The previous narrowing to doc-controllers +\nplanner-notification recipients made the @-picker useless in practice\n\u2014 the only person with both perms in a given org is often the\noperator themselves, so @-mentions degraded to self-mentions. The FE\nMentions component filters by typed prefix; the API is intentionally\npermissive.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/slots/{slot_id}": {"patch": {"operationId": "projects_api_team_request_slots_update_team_request_slot", "summary": "Update Team Request Slot", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Patch a single slot's certs and/or promote it to lead.\n\n- ``required_certificate_ids``: when provided, replaces the slot's set.\n- ``is_lead=True``: transfers leadership to this slot (auto-demotes the\n previous lead). ``is_lead=False`` is rejected \u2014 leadership only moves\n via promotion of another slot.\n- DRAFT: any user with project access; SUBMITTED: doc-control only.", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestSlotUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/slots/{slot_id}/approve": {"post": {"operationId": "projects_api_team_request_slots_approve_team_request_slot", "summary": "Approve Team Request Slot", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Planner approves the WMS-proposed person on this slot.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/slots/{slot_id}/verify": {"post": {"operationId": "projects_api_team_request_slots_verify_team_request_slot", "summary": "Verify Team Request Slot", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Document Controller marks the slot's bound PPRSI as APPROVED.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/slots/{slot_id}/reject": {"post": {"operationId": "projects_api_team_request_slots_reject_team_request_slot", "summary": "Reject Team Request Slot", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Document Controller rejects the slot's bound PPRSI.", "tags": ["projects.team-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SlotRejectPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/slots/{slot_id}/unreject": {"post": {"operationId": "projects_api_team_request_slots_unreject_team_request_slot", "summary": "Unreject Team Request Slot", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Document Controller clears a rejection, returning the PPRSI to PLANNED.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/team-requests/{team_request_id}/slots/{slot_id}/unverify": {"post": {"operationId": "projects_api_team_request_slots_unverify_team_request_slot", "summary": "Unverify Team Request Slot", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "team_request_id", "schema": {"title": "Team Request Id", "type": "integer"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamRequestResponse"}}}}}, "description": "Document Controller resets the slot's bound PPRSI back to PLANNED.", "tags": ["projects.team-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/reporting-requirements": {"get": {"operationId": "projects_api_reporting_requirements_list_reporting_requirements", "summary": "List Reporting Requirements", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectRequirementResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["projects.reporting-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_reporting_requirements_create_reporting_requirement", "summary": "Create Reporting Requirement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["projects.reporting-requirements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/reporting-requirements/options": {"get": {"operationId": "projects_api_reporting_requirements_get_reporting_requirement_options", "summary": "Get Reporting Requirement Options", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementOptionsResponse"}}}}}, "description": "The project's offer services + scope turbines for the modal.\n\nRegistered before ``/{requirement_id}`` so the literal path segment\nisn't parsed as an integer id by django-ninja's route matcher.", "tags": ["projects.reporting-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/reporting-requirements/{requirement_id}": {"get": {"operationId": "projects_api_reporting_requirements_get_reporting_requirement", "summary": "Get Reporting Requirement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["projects.reporting-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_reporting_requirements_update_reporting_requirement", "summary": "Update Reporting Requirement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["projects.reporting-requirements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_reporting_requirements_delete_reporting_requirement", "summary": "Delete Reporting Requirement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["projects.reporting-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/reporting-requirements/{requirement_id}/send": {"post": {"operationId": "projects_api_reporting_requirements_send_reporting_requirement", "summary": "Send Reporting Requirement", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "description": "DRAFT \u2192 PENDING (one-way). cru then pulls it and drives the rest.", "tags": ["projects.reporting-requirements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/familiarity/check": {"get": {"operationId": "projects_api_reporting_requirements_cru_familiarity_check", "summary": "Familiarity Check", "parameters": [{"in": "query", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}, {"in": "query", "name": "operator_sub", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Operator Sub"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GateCheckResponse"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/familiarity": {"post": {"operationId": "projects_api_reporting_requirements_cru_mark_familiar", "summary": "Mark Familiar", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FamiliarityResponse"}}}}}, "tags": ["reporting-requirements.cru"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/FamiliarityCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements": {"get": {"operationId": "projects_api_reporting_requirements_cru_list_requirements", "summary": "List Requirements", "parameters": [{"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"enum": ["DRAFT", "PENDING", "ACTIVE", "INACTIVE", "DECLINED"], "type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectRequirementResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_reporting_requirements_cru_create_requirement", "summary": "Create Requirement", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CruProjectRequirementCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/{requirement_id}": {"get": {"operationId": "projects_api_reporting_requirements_cru_get_requirement", "summary": "Get Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_reporting_requirements_cru_update_requirement", "summary": "Update Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_reporting_requirements_cru_delete_requirement", "summary": "Delete Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/{requirement_id}/accept": {"patch": {"operationId": "projects_api_reporting_requirements_cru_accept_requirement", "summary": "Accept Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/{requirement_id}/decline": {"patch": {"operationId": "projects_api_reporting_requirements_cru_decline_requirement", "summary": "Decline Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}, {"in": "query", "name": "reason", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reason"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/{requirement_id}/deactivate": {"patch": {"operationId": "projects_api_reporting_requirements_cru_deactivate_requirement", "summary": "Deactivate Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/{requirement_id}/restore": {"patch": {"operationId": "projects_api_reporting_requirements_cru_restore_requirement", "summary": "Restore Requirement", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectRequirementResponse"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/reporting-requirements/{requirement_id}/history": {"get": {"operationId": "projects_api_reporting_requirements_cru_requirement_history", "summary": "Requirement History", "parameters": [{"in": "path", "name": "requirement_id", "schema": {"title": "Requirement Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RequirementVersionResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["reporting-requirements.cru"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/set-options": {"get": {"operationId": "projects_api_set_request_get_set_options", "summary": "Get Set Options", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"type": "object"}, "title": "Response", "type": "array"}}}}}, "description": "Robot sets pickable for a new Set Request.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/item-categories": {"get": {"operationId": "projects_api_set_request_list_set_request_item_categories", "summary": "List Set Request Item Categories", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ItemCategoryListResponse"}}}}}, "description": "The ItemCategory lookup the FE renders as the line-category dropdown.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/items": {"get": {"operationId": "projects_api_set_request_list_set_request_items", "summary": "List Set Request Items", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "category_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ItemListResponse"}}}}}, "description": "Catalog of selectable descriptions for the item dropdowns.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_set_request_create_set_request_item", "summary": "Create Set Request Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ItemResponse"}}}}}, "description": "Add a user-defined entry to the shared item catalog (idempotent on duplicate).", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ItemCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/items/{item_id}": {"patch": {"operationId": "projects_api_set_request_update_set_request_item", "summary": "Update Set Request Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ItemResponse"}}}}}, "description": "Rename a catalog entry. Cascades the rename to existing SR rows.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ItemUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "projects_api_set_request_delete_set_request_item", "summary": "Delete Set Request Item", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "item_id", "schema": {"title": "Item Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}}, "description": "Soft-delete a catalog entry. Existing SR rows keep their text.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/offer-pairs": {"get": {"operationId": "projects_api_set_request_get_offer_pairs", "summary": "Get Offer Pairs", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OfferPairsResponse"}}}}}, "description": "Every (location, service) pair on the latest commercial offer.\n\nEach pair becomes one row in the SR create modal's combined picker.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/inherit-candidates": {"get": {"operationId": "projects_api_set_request_get_inherit_candidates", "summary": "Get Inherit Candidates", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "robot_set_id", "schema": {"title": "Robot Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SetRequestInheritCandidate"}, "title": "Response", "type": "array"}}}}}, "description": "Prior PICKED_UP SRs for this robot set, across all projects.\n\n``project_id`` anchors routing/permissions only \u2014 a set's last picked-up\nSR usually lives on the project it just left.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/prefill-options": {"get": {"operationId": "projects_api_set_request_get_prefill_options", "summary": "Get Prefill Options", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "pprs_id", "schema": {"title": "Pprs Id", "type": "integer"}, "required": true}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "region", "schema": {"anyOf": [{"enum": ["EU", "NA"], "type": "string"}, {"type": "null"}], "title": "Region"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestPrefillOptionsResponse"}}}}}, "description": "Suggested consumables + summary for the create modal.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Service Ids"}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests": {"post": {"operationId": "projects_api_set_request_create_set_request", "summary": "Create Set Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "Create a DRAFT Set Request bound to a planning PPRS.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "projects_api_set_request_list_set_requests", "summary": "List Set Requests", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SetRequestResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}": {"get": {"operationId": "projects_api_set_request_get_set_request", "summary": "Get Set Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "projects_api_set_request_update_set_request", "summary": "Update Set Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "Edit a Set Request.\n\nField-aware status gate: notes / kind / items are editable only in\nDRAFT / SUBMITTED / REJECTED, while the mobilization date\n(``needed_by_date``) stays editable in every live status up to\nmobilization \u2014 all except the terminal PICKED_UP / CANCELLED.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/events": {"get": {"operationId": "projects_api_set_request_list_set_request_events", "summary": "List Set Request Events", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SetRequestEventResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Merged status-change + activity timeline.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/notes": {"post": {"operationId": "projects_api_set_request_create_set_request_note", "summary": "Create Set Request Note", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestEventResponse"}}}}}, "description": "Append a free-form note (with optional @-mentions) to a SR's timeline.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestNoteCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/mention-candidates": {"get": {"operationId": "projects_api_set_request_list_set_request_mention_candidates", "summary": "List Set Request Mention Candidates", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MentionCandidateListResponse"}}}}}, "description": "Users available for @-mention on a SR note.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/submit": {"post": {"operationId": "projects_api_set_request_submit_set_request", "summary": "Submit Set Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "DRAFT -> SUBMITTED.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/approve-current": {"post": {"operationId": "projects_api_set_request_approve_current_set", "summary": "Approve Current Set", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "Planner approves the currently-bound robot set.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestApproveCurrent"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/change-set-and-approve": {"post": {"operationId": "projects_api_set_request_change_set_and_approve", "summary": "Change Set And Approve", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "Planner swaps the ROBOT PPRSI to a different robot set and approves.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestChangeAndApprove"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/reject": {"post": {"operationId": "projects_api_set_request_reject_set_request", "summary": "Reject Set Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "SUBMITTED -> REJECTED. Planner rejects with a mandatory reason.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestReject"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/cancel": {"post": {"operationId": "projects_api_set_request_cancel_set_request", "summary": "Cancel Set Request", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "Any non-terminal -> CANCELLED. Idempotent.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/mark-ready": {"post": {"operationId": "projects_api_set_request_mark_set_request_ready", "summary": "Mark Set Request Ready", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "MRO confirms (or undoes) the 'set built' readiness gate.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/SetRequestReadinessToggle"}, {"type": "null"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/confirm-it": {"post": {"operationId": "projects_api_set_request_confirm_set_request_it", "summary": "Confirm Set Request It", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "IT confirms (or undoes) Starlink/setup done. Captured, never blocks pickup.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/SetRequestReadinessToggle"}, {"type": "null"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/confirm-ppe": {"post": {"operationId": "projects_api_set_request_confirm_set_request_ppe", "summary": "Confirm Set Request Ppe", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "PPE coordinator confirms (or undoes) that the set PPE is in the bus.", "tags": ["projects.set-requests"], "requestBody": {"content": {"application/json": {"schema": {"anyOf": [{"$ref": "#/components/schemas/SetRequestReadinessToggle"}, {"type": "null"}]}}}, "required": false}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-requests/{set_request_id}/mark-picked-up": {"post": {"operationId": "projects_api_set_request_mark_set_request_picked_up", "summary": "Mark Set Request Picked Up", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "set_request_id", "schema": {"title": "Set Request Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetRequestResponse"}}}}}, "description": "READY -> PICKED_UP. The set-pickup permission holder (MRO) confirms it.", "tags": ["projects.set-requests"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs": {"get": {"operationId": "projects_api_set_demob_list_set_demobs", "summary": "List Set Demobs", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SetDemobResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["projects.set-demobs"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "projects_api_set_demob_create_set_demob", "summary": "Create Set Demob", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobResponse"}}}}}, "description": "Manually create an APPROVED demob for a case the sweep won't catch.", "tags": ["projects.set-demobs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/anchor-candidates": {"get": {"operationId": "projects_api_set_demob_list_set_demob_anchor_candidates", "summary": "List Set Demob Anchor Candidates", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SetDemobAnchorCandidate"}, "title": "Response", "type": "array"}}}}}, "description": "ROBOT PPRSIs a manual demob can anchor on (picker for Create demob).", "tags": ["projects.set-demobs"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/{demob_id}": {"get": {"operationId": "projects_api_set_demob_get_set_demob", "summary": "Get Set Demob", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "demob_id", "schema": {"title": "Demob Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobResponse"}}}}}, "tags": ["projects.set-demobs"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/{demob_id}/events": {"get": {"operationId": "projects_api_set_demob_list_set_demob_events", "summary": "List Set Demob Events", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "demob_id", "schema": {"title": "Demob Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SetDemobEventResponse"}, "title": "Response", "type": "array"}}}}}, "description": "The change log: approvals, date adjustments, rejections, drift flags.", "tags": ["projects.set-demobs"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/{demob_id}/approve": {"post": {"operationId": "projects_api_set_demob_approve_set_demob", "summary": "Approve Set Demob", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "demob_id", "schema": {"title": "Demob Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobResponse"}}}}}, "description": "Approve a PLANNED demob, confirming or overriding the return date.", "tags": ["projects.set-demobs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobApprove"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/{demob_id}/adjust-date": {"post": {"operationId": "projects_api_set_demob_adjust_set_demob_date", "summary": "Adjust Set Demob Date", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "demob_id", "schema": {"title": "Demob Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobResponse"}}}}}, "description": "Edit an APPROVED demob's return date (logged in the change log).", "tags": ["projects.set-demobs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobAdjustDate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/{demob_id}/reject": {"post": {"operationId": "projects_api_set_demob_reject_set_demob", "summary": "Reject Set Demob", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "demob_id", "schema": {"title": "Demob Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobResponse"}}}}}, "description": "Reject a PLANNED demob (sticky \u2014 the sweep won't recreate it).", "tags": ["projects.set-demobs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobReject"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/set-demobs/{demob_id}/cancel": {"post": {"operationId": "projects_api_set_demob_cancel_set_demob", "summary": "Cancel Set Demob", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "demob_id", "schema": {"title": "Demob Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobResponse"}}}}}, "description": "Cancel an APPROVED demob (manual reversal).", "tags": ["projects.set-demobs"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetDemobCancel"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/readiness/requests": {"get": {"operationId": "projects_api_readiness_get_requests_readiness", "summary": "Get Requests Readiness", "parameters": [{"in": "query", "name": "statuses", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Statuses"}, "required": false}, {"in": "query", "name": "include_null_status", "schema": {"default": false, "title": "Include Null Status", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReadinessResponse"}}}}}, "description": "Return all readiness rows; optionally filter by project status code.\n\n``statuses``: comma-separated ProjectStatus codes (case-insensitive).\nWhen omitted, no status filter is applied. ``include_null_status`` keeps\nrows whose project has no status (only meaningful with ``statuses``).", "tags": ["readiness"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/board-data": {"get": {"operationId": "dispatch_api_board_get_board_data", "summary": "Get dispatching board data", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}, {"in": "query", "name": "until", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Until"}, "required": false}, {"in": "query", "name": "include_backlog", "schema": {"default": true, "title": "Include Backlog", "type": "boolean"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BoardDataResponse"}}}}}, "description": "Return all data needed for the dispatching board.\n\nAggregates:\n- Project resource sets with their members\n- All project workorders (service + admin) with resource assignments\n- Service order lines grouped for the panel\n\nWhen both ``since`` and ``until`` are supplied, the workorders list is\nfiltered to a date window \u2014 useful for the dispatching console where\nonly the relevant working set should be returned. The five filter\nclauses are: scheduled in window, mandatory in window,\nassigned-but-unscheduled, due-dated backlog within\n``dispatch.managers.board_reads.BACKLOG_HORIZON_DAYS``, and unassigned\nWOs from PLANNING/EXECUTION projects (regardless of due date). Without\nthe params, the legacy behaviour is preserved (returns all non-cancelled\nworkorders).\n\nThe windowed result also folds in real work that was logged but never\nformally dispatched (DISP-4368, see\n``dispatch.managers.logged_unplanned._get_logged_unplanned_workorders``)\n-- those rows carry ``is_logged_unplanned=True`` with a planned window\nderived from the actual logged activity times, and are dropped entirely\nif that derived window clashes with a genuinely planned entry for one of\nthe same resources.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/board-turbines": {"get": {"operationId": "dispatch_api_board_get_board_turbines", "summary": "Get per-turbine status rollup for the dispatching board", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BoardTurbinesResponse"}}}}}, "description": "Per-turbine status + activity-group completion for the whole project,\nregardless of the board's date window (see\n``dispatch.managers.board_reads._get_project_turbines``).\n\nKept on its own query, decoupled from ``board-data``'s per-mutation\nrefetch cycle, since this scan covers every non-cancelled workorder in\nthe project and dominates payload size.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/backlog": {"get": {"operationId": "dispatch_api_board_get_backlog", "summary": "Server-filtered, paginated work-order list for the dispatch sidebar", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "q", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Q"}, "required": false}, {"in": "query", "name": "assignment", "schema": {"default": "open", "title": "Assignment", "type": "string"}, "required": false}, {"in": "query", "name": "statuses", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Statuses"}, "required": false}, {"in": "query", "name": "kinds", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Kinds"}, "required": false}, {"in": "query", "name": "service_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Codes"}, "required": false}, {"in": "query", "name": "turbine_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Ids"}, "required": false}, {"in": "query", "name": "logged_unplanned", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Logged Unplanned"}, "required": false}, {"in": "query", "name": "page", "schema": {"default": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 300, "title": "Page Size", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BacklogPageResponse"}}}}}, "description": "Sidebar work-order list with server-side filtering and pagination.\n\nA large project can hold thousands of unassigned workorders \u2014 shipping\nthem all inside ``board-data`` made the board slow and the browser\nunstable, so the sidebar reads this endpoint instead (and ``board-data``\nis called with ``include_backlog=false``).\n\nFilters: ``q`` full-text-ish search (name, description, service code,\nturbine name, SO number); ``assignment`` open|unassigned|assigned, where\n``assigned`` means an active resource-set link EXISTS, ``unassigned`` means\nnone does, and ``open`` (the default, what the sidebar shows) is\nunassigned work PLUS any ``IN_PROGRESS`` workorder regardless of its team\nlink -- running work that was dispatched earlier still has to be found\nand moved to the next day when it does not finish, and it normally still\ncarries its team; ``statuses``/``kinds``/``service_codes`` as\ncomma-separated lists; ``logged_unplanned`` narrows to (``true``) or\nexcludes (``false``) real work logged with no formal dispatch (DISP-4368)\n-- these rows are already part of the unassigned scope and otherwise\nindistinguishable by status from any untouched backlog WO, so this is\nwhat makes them findable across a project's full backlog rather than only\non whichever board day/week they happen to be scrolled to. ``counts`` in\nthe response carries facet totals for the filter chips, each computed\nbefore its own facet filter (standard faceting), over the search +\nassignment scope.\n\nSee ``dispatch.managers.backlog._get_backlog_sync`` for the query shape:\nthe assignment counts come from one query (grouping on a ``has_team``\nannotation rather than filtering `base` twice), and the three facet\nbreakdowns (statuses/kinds/services) come from one grouped query across\nall three dimensions at once, summed per dimension in Python.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/board-weather": {"get": {"operationId": "dispatch_api_board_get_board_weather", "summary": "Get dispatching board weather", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "date", "schema": {"format": "date", "title": "Date", "type": "string"}, "required": true}, {"in": "query", "name": "project_location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BoardWeatherResponse"}}}}}, "description": "Hourly weather forecast for a project location on ``date``.\n\nThe whole UTC day, read from the ``weather_forecast`` cache (kept warm by the scheduled Gust sync). On a\ncache miss for an in-horizon day, the location's bucket is backfilled from\nGust on the fly (one query) and re-read. Fail-soft: returns\n``available=false`` with no hours when the location has no coordinates or no\nforecast is available, so the board always renders.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/dispatch/coverage": {"get": {"operationId": "dispatch_api_board_dispatch_coverage", "summary": "Per-project resource-set coverage by day", "parameters": [{"in": "query", "name": "since", "schema": {"format": "date", "title": "Since", "type": "string"}, "required": true}, {"in": "query", "name": "until", "schema": {"format": "date", "title": "Until", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectCoverageResponse"}, "title": "Response", "type": "array"}}}}}, "description": "For each project active in the window, return the total active resource\nsets and the per-day count of resource sets with at least one workorder\nplanned to start on that day. Coverage % is computed client-side.", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/dispatch/adoption": {"get": {"operationId": "dispatch_api_board_dispatch_adoption", "summary": "Teams x dates table of what the board dispatched (OH-4167)", "parameters": [{"in": "query", "name": "since", "schema": {"format": "date", "title": "Since", "type": "string"}, "required": true}, {"in": "query", "name": "until", "schema": {"format": "date", "title": "Until", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdoptionTableResponse"}}}}}, "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/dispatch/supervisor-options": {"get": {"operationId": "dispatch_api_board_list_supervisor_options", "summary": "List BTO supervisors and the core projects they supervise", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SupervisorOption"}, "title": "Response", "type": "array"}}}}}, "description": "Supervisors exist only on BTO rosters (``team_members`` entries with\nrole \"Supervisor\") \u2014 there is no core-project supervisor field yet\n(OH-2774).", "tags": ["dispatch.board"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/assign": {"post": {"operationId": "dispatch_api_board_workorders_assign_workorder", "summary": "Assign workorder to resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Assign a workorder to a resource set and set planned datetimes.\n\nFinds the ProjectResourceSet that contains the given resource_ids,\nensures a WorkorderResourceSet links the workorder to it, and sets\nWorkorder.planned_start_datetime / planned_end_datetime.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AssignWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/assign-bulk": {"post": {"operationId": "dispatch_api_board_workorders_assign_workorders_bulk", "summary": "Bulk assign workorders to resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Assign multiple workorders to resources and set planned datetimes.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkAssignWorkordersPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/unassign": {"post": {"operationId": "dispatch_api_board_workorders_unassign_workorder", "summary": "Unassign workorder from resources", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Remove all resource assignments and clear planned datetimes for a workorder.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UnassignWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/workorders/{workorder_id}": {"delete": {"operationId": "dispatch_api_board_workorders_delete_admin_workorder", "summary": "Soft-delete an administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a dispatcher-created ADMIN workorder (and its dispatch links).\n\nOnly administrative work (ADMIN/OFFICE) may be deleted from the board \u2014 field\nservice work is driven by the service order and must not be removed here.", "tags": ["dispatch.board-workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/admin-workorder/{workorder_id}": {"patch": {"operationId": "dispatch_api_board_workorders_update_admin_workorder", "summary": "Edit an existing administrative workorder's name/duration", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateAdminWorkorderResponse"}}}}}, "description": "DISP-2892: the drawer's edit-mode pencil icon for an ADMIN workorder.\n\nName and duration only -- assignee is fixed after creation (no endpoint\nfor it exists), and activities are edited individually via\n``update_workorder_activity`` below.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateAdminWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/workorders/{workorder_id}/turbine": {"post": {"operationId": "dispatch_api_board_workorders_set_workorder_turbine", "summary": "Set the turbine for a scope-dispatched workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Bind a turbine to a scope-dispatched (DISP-2259) workorder + its SOL,\nonce the crew knows which asset they're actually working on. No-op if\nalready set to the same turbine; rejects overwriting a different one.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetWorkorderTurbinePayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/admin-workorder": {"post": {"operationId": "dispatch_api_board_workorders_create_admin_workorder", "summary": "Create an ADMIN workorder assigned to a single technician", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateAdminWorkorderResponse"}}}}}, "description": "Create a standalone ADMIN workorder pinned to one individual technician.\n\nThe workorder is scoped to ``project_id`` and inherits the project's\n``requesting_customer`` (so it is visible under the customer-scoped RLS\npolicy and returned by ``board-data``). It is created with\n``type=ADMIN`` / ``status=NOT_STARTED`` via the canonical\n``WorkorderManager.gql_create`` path, then linked to the project resource\nset the technician belongs to and pinned to that individual \u2014 reusing the\nsame assignment machinery as ``/assign`` so the board routes it into the\nmember's person lane.\n\nThe manager creates, links, and pins the workorder inside one\ntransaction: if the resource-set or assignee step fails, the workorder\nmust not be left committed without its dispatch links (mirrors the\natomic pattern in ``_assign_workorders_bulk_sync``).", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateAdminWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/workorders/{workorder_id}/activities": {"post": {"operationId": "dispatch_api_board_workorders_add_workorder_activity", "summary": "Add an activity to an existing administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddWorkorderActivityResponse"}}}}}, "description": "Add one WorkorderActivity to an already-created ADMIN workorder\n(DISP-2379) -- lets a dispatcher extend scope after creation, the same\nway activities picked at create time work.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminActivityInput"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/workorders/{workorder_id}/activities/{activity_id}": {"patch": {"operationId": "dispatch_api_board_workorders_update_workorder_activity", "summary": "Edit an activity on an existing administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}, {"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateWorkorderActivityResponse"}}}}}, "description": "DISP-2892: the drawer's edit-mode counterpart to\n``add_workorder_activity`` -- same remaining-budget rule, but excluding\nthis activity's own current duration from the \"other activities\" total.", "tags": ["dispatch.board-workorders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateWorkorderActivityPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_board_workorders_delete_workorder_activity", "summary": "Remove an activity from an existing administrative workorder", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "workorder_id", "schema": {"title": "Workorder Id", "type": "integer"}, "required": true}, {"in": "path", "name": "activity_id", "schema": {"title": "Activity Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete one WorkorderActivity from an ADMIN workorder (FEAT-2554\nfollow-up) -- the undo of ``add_workorder_activity`` above.\n\nRefuses to remove the workorder's last remaining activity: that would\nrecreate the exact \"inert on mobile\" state DISP-2379 exists to prevent.", "tags": ["dispatch.board-workorders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/scope-groups": {"get": {"operationId": "dispatch_api_scope_commitments_list_scope_groups", "summary": "List service/component-type buckets of scope items available for team dispatch", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScopeGroupResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Group real per-turbine scope items by (service, component_type) --\nsee ``list_scope_groups_sync``.", "tags": ["dispatch.scope-commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/scope-workorder": {"post": {"operationId": "dispatch_api_scope_commitments_create_scope_workorder", "summary": "Reserve pending scope-dispatch commitments for a team against a scope bucket", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateScopeWorkorderResponse"}}}}}, "description": "Dispatch a team against a scope bucket -- no turbine pinned yet.", "tags": ["dispatch.scope-commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateScopeWorkorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/scope-commitments/{commitment_id}/turbines": {"get": {"operationId": "dispatch_api_scope_commitments_list_scope_commitment_turbine_options", "summary": "List turbines a pending scope-dispatch commitment can resolve to", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ScopeCommitmentTurbineOption"}, "title": "Response", "type": "array"}}}}}, "description": "Turbines with at least one free (not actively dispatched) scope row in\nthis commitment's bucket \u2014 the drawer's picker offers ONLY these, so a\ndispatcher can't pick a turbine that is out of scope or already claimed.\n\nShared with the GraphQL ``scopeCommitmentTurbineOptions`` query instead of\nduplicating the filter -- see ``list_scope_commitment_turbine_options_sync``.", "tags": ["dispatch.scope-commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/scope-commitments/{commitment_id}/turbine": {"post": {"operationId": "dispatch_api_scope_commitments_resolve_scope_commitment_turbine", "summary": "Resolve a pending scope-dispatch commitment by picking a turbine", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "OpsHub fallback for AeroTask's resolveScopeCommitmentTurbine.", "tags": ["dispatch.scope-commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveScopeCommitmentPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/scope-commitments/{commitment_id}": {"patch": {"operationId": "dispatch_api_scope_commitments_reschedule_scope_commitment", "summary": "Reschedule a still-pending scope-dispatch commitment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Move a still-PENDING commitment's planned window, and optionally its\nteam -- see ``reschedule_scope_commitment_sync``.", "tags": ["dispatch.scope-commitments"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RescheduleScopeCommitmentPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_scope_commitments_cancel_scope_commitment", "summary": "Cancel a still-pending scope-dispatch commitment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "commitment_id", "schema": {"title": "Commitment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft-delete a still-PENDING commitment, freeing its capacity.", "tags": ["dispatch.scope-commitments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/day-commentary": {"post": {"operationId": "dispatch_api_board_annotations_create_day_commentary", "summary": "Add a dispatcher's day-commentary note to a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DayCommentaryResponse"}}}}}, "description": "Record a free-form dispatcher note about one day on a project\n(DISP-2285). Internal-only: no GraphQL field exposes this, so it never\nreaches AeroTask.", "tags": ["dispatch.board-annotations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DayCommentaryPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "dispatch_api_board_annotations_list_day_commentary", "summary": "List a project's day-commentary notes for one day", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "date", "schema": {"format": "date", "title": "Date", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DayCommentaryResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/service-kpis": {"get": {"operationId": "dispatch_api_board_annotations_list_service_kpis", "summary": "List KPI (benchmark duration) settings for every service used on a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceKpiResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Every service this project's scope references, with its effective KPI\nduration -- this project's own override (DISP-2988) if one is set, else\nthe flat `Service.default_kpi_minutes` (DISP-2925). Feeds the board's\n\"Service KPIs\" settings pane.", "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/service-kpis/{service_id}": {"put": {"operationId": "dispatch_api_board_annotations_set_service_kpi", "summary": "Set a project's KPI override for one service", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceKpiResponse"}}}}}, "description": "Set (or replace) this project's KPI duration override for a service\n(DISP-2988) -- the value the dispatching board uses instead of the flat\n`Service.default_kpi_minutes` for every scope-based dispatch of this\nservice on this project.", "tags": ["dispatch.board-annotations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SetServiceKpiPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "dispatch_api_board_annotations_delete_service_kpi", "summary": "Clear a project's KPI override for one service, reverting to the global default", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "path", "name": "service_id", "schema": {"title": "Service Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceKpiResponse"}}}}}, "description": "Remove this project's KPI override for a service (DISP-2988), reverting\nthe board back to `Service.default_kpi_minutes` (or a `ServiceComponent`\noverride, if one applies to the bucket).", "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/dispatch/team-messages": {"post": {"operationId": "dispatch_api_board_annotations_create_team_message", "summary": "Send a dispatcher message to a team", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TeamMessageResponse"}}}}}, "description": "Create a dated free-form note from the dispatcher to one team\n(DISP-2288). Answered once from AeroTask via the ``respondToTeamMessage``\nGraphQL mutation -- this endpoint only creates the message.", "tags": ["dispatch.board-annotations"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateTeamMessagePayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "dispatch_api_board_annotations_list_team_messages", "summary": "List dispatcher messages to teams for a project", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "integer"}, "required": true}, {"in": "query", "name": "since", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Since"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TeamMessageResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Team messages for the project, oldest first (DISP-2288).", "tags": ["dispatch.board-annotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{code}/upcoming-rotations": {"get": {"operationId": "projects_api_upcoming_rotations_list_upcoming_rotations", "summary": "List Upcoming Rotations", "parameters": [{"in": "path", "name": "code", "schema": {"title": "Code", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/UpcomingRotationResponse"}, "title": "Response", "type": "array"}}}}}, "description": "List the project's WMS rotations (pending/confirmed/cancelled).\n\nRead-only and informational. Degrades to an empty list when WMS is\nunconfigured or unreachable \u2014 the client never raises.", "tags": ["projects.upcoming-rotations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders": {"get": {"operationId": "accounting_api_get_sales_orders", "summary": "Get Sales Orders", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesOrder"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve all sales orders for a given project.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "accounting_api_create_sales_order", "summary": "Create Sales Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrder"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create sales order for given project", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/legacy": {"post": {"operationId": "accounting_api_create_sales_order_old", "summary": "Create Sales Order Old", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrder"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Legacy sales order create endpoint (kept for testing).", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderPOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/create-background": {"post": {"operationId": "accounting_api_create_sales_order_in_background", "summary": "Create Sales Order In Background", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageWithSuccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create sales order in background for given project.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/status": {"get": {"operationId": "accounting_api_get_sales_order_status", "summary": "Get Sales Order Status", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CombinedSalesOrderStatus"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get combined sales order creation and sync status for a project.\n\nReturns creation status and sync status (if sales order exists).", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}": {"delete": {"operationId": "accounting_api_delete_sales_order", "summary": "Delete Sales Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete sales order for given project", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/line-items": {"get": {"operationId": "accounting_api_get_sales_order_line_items", "summary": "Get Sales Order Line Items", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesOrderLineItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve all line items for a specific sales order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/line-items/summary": {"get": {"operationId": "accounting_api_get_sales_order_line_items_summary", "summary": "Get Sales Order Line Items Summary", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceRate"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve summary of all line items for a specific sales order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/line-items/tree": {"get": {"operationId": "accounting_api_get_sales_order_line_items_tree", "summary": "Get Sales Order Line Items Tree", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesOrderLineItemTLNode"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve all line items in tree structure, i.e. blades as child nodes of turbines.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/charges": {"get": {"operationId": "accounting_api_get_charges", "summary": "Get Charges", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Charge"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return list of charges by sales order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "accounting_api_update_charges_bulk", "summary": "Update Charges Bulk", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Charge"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update multiple charges in bulk.\n\nOnly charges with status DRAFT can be updated.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ChargeBulkPATCHItem"}, "title": "Body", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "accounting_api_delete_charges_bulk", "summary": "Delete Charges Bulk", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete multiple charges in bulk.\n\nOnly charges with status DRAFT can be deleted.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkDELETE"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/email-sends": {"get": {"operationId": "accounting_api_get_email_sends", "summary": "Get Email Sends", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/EmailSendLogResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return a project's sent-email history, most recent first.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/charges/summary": {"get": {"operationId": "accounting_api_get_charges_summary", "summary": "Get Charges Summary", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Date From"}, "required": false}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Date To"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return pre-aggregated charge totals from local DB, optionally filtered by date range.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/line-items/{line_item_id}/charges": {"post": {"operationId": "accounting_api_create_charge", "summary": "Create Charge", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_item_id", "schema": {"title": "Line Item Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Charge"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a charge.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargePOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/line-items/{line_item_id}/charges/{charge_id}": {"patch": {"operationId": "accounting_api_update_charge", "summary": "Update Charge", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_item_id", "schema": {"title": "Line Item Id", "type": "integer"}, "required": true}, {"in": "path", "name": "charge_id", "schema": {"title": "Charge Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Charge"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update a charge.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargePATCH"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "accounting_api_delete_charge", "summary": "Delete Charge", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "path", "name": "line_item_id", "schema": {"title": "Line Item Id", "type": "integer"}, "required": true}, {"in": "path", "name": "charge_id", "schema": {"title": "Charge Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a charge.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/charges/bulk-approve": {"post": {"operationId": "accounting_api_bulk_approve_charges", "summary": "Bulk Approve Charges", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkApproveResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkApprove"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/invoices": {"get": {"operationId": "accounting_api_get_invoices", "summary": "Get Invoices", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AccountingInvoice"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get all invoices for a sales order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "accounting_api_create_invoice", "summary": "Create Invoice", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateInvoiceResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create invoice for given sales order.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateSalesOrderInvoicePOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/invoices/create-background": {"post": {"operationId": "accounting_api_create_invoice_in_background", "summary": "Create Invoice In Background", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageWithSuccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create invoice in background for given sales order.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateSalesOrderInvoicePOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/diff-asset-names": {"get": {"operationId": "accounting_api_get_sales_order_diff_asset_names", "summary": "Get Sales Order Diff Asset Names", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"additionalProperties": {"$ref": "#/components/schemas/PatchStrValue"}, "title": "Response", "type": "object"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get Sales Order diff asset names.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "accounting_api_create_sales_order_diff_asset_names_patch", "summary": "Create Sales Order Diff Asset Names Patch", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AssetPatchGET"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create Sales Order diff asset names patch.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "accounting_api_apply_sales_order_diff_asset_names_patch", "summary": "Apply Sales Order Diff Asset Names Patch", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Apply Sales Order diff asset names patch.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AssetPatchPATCH"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/idle-hour-time-windows": {"get": {"operationId": "accounting_api_get_idle_hour_time_windows", "summary": "Get Idle Hour Time Windows", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "query", "name": "charge_date", "schema": {"format": "date", "title": "Charge Date", "type": "string"}, "required": true}, {"in": "query", "name": "robot_set_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "required": false}, {"in": "query", "name": "robot_set_name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IdleHourTimeWindowsResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Build idle-hour delay windows for a charge date and robot set.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/sync-offer": {"post": {"operationId": "accounting_api_sync_offer_line_items", "summary": "Sync Offer Line Items", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageWithSuccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Sync offer line items for Sales Order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/sync-background": {"post": {"operationId": "accounting_api_sync_sales_order_in_background", "summary": "Sync Sales Order In Background", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Trigger background sync of Sales Order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/sync-core": {"post": {"operationId": "accounting_api_sync_core_sales_order", "summary": "Sync Core Sales Order", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageWithSuccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Sync core sales order with core-only reconciliation rules.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/sync-core-background": {"post": {"operationId": "accounting_api_sync_core_sales_order_in_background", "summary": "Sync Core Sales Order In Background", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Trigger background core sync of Sales Order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/sync-delay-charges": {"post": {"operationId": "accounting_api_sync_delay_charges", "summary": "Sync Delay Charges", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "query", "name": "filter_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Filter Date"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SyncDelayChargesResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Sync delay charges from local core.Delay records to NetSuite.\n\nAggregates core.Delay rows for the given project (by robot set and date)\nand creates corresponding charges in NetSuite for non-asset line items.\n\nUses the delay ID for idempotency - delays that already have charges\nwill be skipped.\n\nQuantity is calculated based on delay duration (8 hours = 1 day).", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/re-evaluate-require-po": {"post": {"operationId": "accounting_api_re_evaluate_require_po", "summary": "Re Evaluate Require Po", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MessageWithSuccess"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Re-evaluate REQUIRE_PO charges for all POs linked to a project.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/accounting/comments": {"get": {"operationId": "accounting_api_list_accounting_comments", "summary": "List Accounting Comments", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "comment_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Comment Date"}, "required": false}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "required": false}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "End Date"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AccountingComment"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List accounting comments for a project.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "accounting_api_create_accounting_comment", "summary": "Create Accounting Comment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountingComment"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a new accounting comment for a project.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountingCommentPOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/accounting/comments/{comment_id}": {"patch": {"operationId": "accounting_api_update_accounting_comment", "summary": "Update Accounting Comment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountingComment"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update an accounting comment.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountingCommentPATCH"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "accounting_api_delete_accounting_comment", "summary": "Delete Accounting Comment", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete an accounting comment.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/accounting/suggestion-decisions": {"get": {"operationId": "accounting_api_list_suggestion_decisions", "summary": "List Suggestion Decisions", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "decision_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Decision Date"}, "required": false}, {"in": "query", "name": "set_name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Set Name"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SuggestionDecisionSchema"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List suggestion decisions for a project.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "accounting_api_upsert_suggestion_decision", "summary": "Upsert Suggestion Decision", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuggestionDecisionSchema"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create or update a suggestion decision.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuggestionDecisionPOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "accounting_api_delete_suggestion_decision", "summary": "Delete Suggestion Decision", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a suggestion decision.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SuggestionDecisionDELETE"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/accounting/team-workload": {"get": {"operationId": "accounting_api_get_team_workload", "summary": "Get Team Workload", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "required": false}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "End Date"}, "required": false}, {"in": "query", "name": "sales_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sales Order Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TeamWorkloadDay"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return daily team workload summary for a project.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/accounting/delays": {"get": {"operationId": "accounting_api_get_delays", "summary": "Get Delays", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "query_date", "schema": {"format": "date", "title": "Query Date", "type": "string"}, "required": true}, {"in": "query", "name": "robot_set_id", "schema": {"title": "Robot Set Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DelayItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List delays for a robot set on a specific day, for idle charge linking.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/accounting/daily-reports": {"get": {"operationId": "accounting_api_get_accounting_daily_reports", "summary": "Get Accounting Daily Reports", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "required": false}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "End Date"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DailyReportsResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return daily reports from local dispatch data for accounting calendar.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/charged-revenue": {"get": {"operationId": "accounting_api_get_charged_revenue", "summary": "Get Charged Revenue", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargedRevenueResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get total charged revenue aggregated from approved charges.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/netsuite/countries": {"get": {"operationId": "accounting_api_get_netsuite_service_countries", "summary": "Get Netsuite Service Countries", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NSServiceCountry"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get active NetSuite service countries.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/turbines-progress": {"get": {"operationId": "accounting_api_get_turbines_progress", "summary": "Get Turbines Progress", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbinesProgress"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Turbine charge progress from local DB for a sales order.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/netsuite/subsidiaries": {"get": {"operationId": "accounting_api_get_netsuite_subsidiaries", "summary": "Get Netsuite Subsidiaries", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NSSubsidiaryListItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get NetSuite subsidiaries, excluding elimination and holding entries.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/service-rates-context": {"get": {"operationId": "accounting_api_get_service_rates_context", "summary": "Get Service Rates Context", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceRateItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Service rates from the latest approved CO \u2014 for OPS_HUB SO sidebars.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/charge-creation-context": {"get": {"operationId": "accounting_api_get_charge_creation_context", "summary": "Get Charge Creation Context", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}, {"in": "query", "name": "co_item_ids", "schema": {"title": "Co Item Ids", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeCreationContext"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return charge creation context for one or more CO line items \u2014 100% local DB, no NS call.\n\n``co_item_ids`` is a comma-separated list: a service priced per asset spans\nseveral CO lines, and the modal needs the assets from all of them.", "tags": ["projects.accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/projects/{project_id}/sales-orders/{sales_order_id}/scope-charges": {"post": {"operationId": "accounting_api_create_scope_charge", "summary": "Create Scope Charge", "parameters": [{"in": "path", "name": "project_id", "schema": {"title": "Project Id", "type": "string"}, "required": true}, {"in": "path", "name": "sales_order_id", "schema": {"title": "Sales Order Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Charge"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Create a charge from a scope item \u2014 ensures NS asset exists and CO price is synced.", "tags": ["projects.accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ScopeChargePOST"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/commercial-offers": {"get": {"operationId": "projects_api_commercial_offers_list_commercial_offers", "summary": "List Commercial Offers", "parameters": [{"in": "query", "name": "page", "schema": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "required": false}, {"in": "query", "name": "page_size", "schema": {"default": 50, "maximum": 200, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false}, {"in": "query", "name": "include_approved", "schema": {"default": false, "title": "Include Approved", "type": "boolean"}, "required": false}, {"in": "query", "name": "required_approver_role", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Required Approver Role"}, "required": false}, {"in": "query", "name": "ordering", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "-id", "title": "Ordering"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CommercialOfferRow"}, "title": "Response", "type": "array"}}}}}, "description": "Return a paginated list of commercial offers filtered by status.", "tags": ["commercial-offers"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/commercial-offers/approve": {"post": {"operationId": "projects_api_commercial_offers_approve_commercial_offers", "summary": "Approve Commercial Offers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommercialOfferBulkApproveResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Approve offers when the requester has the required authority.", "tags": ["commercial-offers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommercialOfferApproveRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/overview": {"get": {"operationId": "accounting_api_v2_get_accounting_overview", "summary": "Get Accounting Overview", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "required": false, "description": "Start date for filtering charges"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}, "required": false, "description": "End date for filtering charges"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by project code (partial matching)", "title": "Search"}, "required": false, "description": "Search by project code (partial matching)"}, {"in": "query", "name": "clients", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client names (comma-separated)", "title": "Clients"}, "required": false, "description": "Filter by client names (comma-separated)"}, {"in": "query", "name": "pm", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project managers (comma-separated)", "title": "Pm"}, "required": false, "description": "Filter by project managers (comma-separated)"}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "required": false, "description": "Filter by regions (comma-separated)"}, {"in": "query", "name": "country", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by countries (comma-separated)", "title": "Country"}, "required": false, "description": "Filter by countries (comma-separated)"}, {"in": "query", "name": "project_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by core project status (comma-separated)", "title": "Project Status"}, "required": false, "description": "Filter by core project status (comma-separated)"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billable service code (comma-separated)", "title": "Service Code"}, "required": false, "description": "Filter by billable service code (comma-separated)"}, {"in": "query", "name": "service_unit_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service unit type (comma-separated)", "title": "Service Unit Type"}, "required": false, "description": "Filter by service unit type (comma-separated)"}, {"in": "query", "name": "robot_set", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robot set (comma-separated)", "title": "Robot Set"}, "required": false, "description": "Filter by robot set (comma-separated)"}, {"in": "query", "name": "total_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue (in project currency)", "title": "Total Revenue Min"}, "required": false, "description": "Minimum total revenue (in project currency)"}, {"in": "query", "name": "total_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue (in project currency)", "title": "Total Revenue Max"}, "required": false, "description": "Maximum total revenue (in project currency)"}, {"in": "query", "name": "total_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in EUR", "title": "Total Revenue Eur Min"}, "required": false, "description": "Minimum total revenue in EUR"}, {"in": "query", "name": "total_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in EUR", "title": "Total Revenue Eur Max"}, "required": false, "description": "Maximum total revenue in EUR"}, {"in": "query", "name": "total_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in USD", "title": "Total Revenue Usd Min"}, "required": false, "description": "Minimum total revenue in USD"}, {"in": "query", "name": "total_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in USD", "title": "Total Revenue Usd Max"}, "required": false, "description": "Maximum total revenue in USD"}, {"in": "query", "name": "total_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in AUD", "title": "Total Revenue Aud Min"}, "required": false, "description": "Minimum total revenue in AUD"}, {"in": "query", "name": "total_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in AUD", "title": "Total Revenue Aud Max"}, "required": false, "description": "Maximum total revenue in AUD"}, {"in": "query", "name": "added_to_invoice_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Min"}, "required": false, "description": "Minimum added to invoice revenue (in project currency)"}, {"in": "query", "name": "added_to_invoice_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Max"}, "required": false, "description": "Maximum added to invoice revenue (in project currency)"}, {"in": "query", "name": "added_to_invoice_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Min"}, "required": false, "description": "Minimum added to invoice revenue in EUR"}, {"in": "query", "name": "added_to_invoice_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Max"}, "required": false, "description": "Maximum added to invoice revenue in EUR"}, {"in": "query", "name": "added_to_invoice_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Min"}, "required": false, "description": "Minimum added to invoice revenue in USD"}, {"in": "query", "name": "added_to_invoice_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Max"}, "required": false, "description": "Maximum added to invoice revenue in USD"}, {"in": "query", "name": "added_to_invoice_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Min"}, "required": false, "description": "Minimum added to invoice revenue in AUD"}, {"in": "query", "name": "added_to_invoice_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Max"}, "required": false, "description": "Maximum added to invoice revenue in AUD"}, {"in": "query", "name": "actual_planned_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Min"}, "required": false, "description": "Minimum actual planned revenue (in project currency)"}, {"in": "query", "name": "actual_planned_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Max"}, "required": false, "description": "Maximum actual planned revenue (in project currency)"}, {"in": "query", "name": "actual_planned_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Min"}, "required": false, "description": "Minimum actual planned revenue in EUR"}, {"in": "query", "name": "actual_planned_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Max"}, "required": false, "description": "Maximum actual planned revenue in EUR"}, {"in": "query", "name": "actual_planned_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Min"}, "required": false, "description": "Minimum actual planned revenue in USD"}, {"in": "query", "name": "actual_planned_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Max"}, "required": false, "description": "Maximum actual planned revenue in USD"}, {"in": "query", "name": "actual_planned_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Min"}, "required": false, "description": "Minimum actual planned revenue in AUD"}, {"in": "query", "name": "actual_planned_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Max"}, "required": false, "description": "Maximum actual planned revenue in AUD"}, {"in": "query", "name": "total_quantity_min", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum total quantity", "title": "Total Quantity Min"}, "required": false, "description": "Minimum total quantity"}, {"in": "query", "name": "total_quantity_max", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum total quantity", "title": "Total Quantity Max"}, "required": false, "description": "Maximum total quantity"}, {"in": "query", "name": "actual_planned_quantity_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned quantity", "title": "Actual Planned Quantity Min"}, "required": false, "description": "Minimum actual planned quantity"}, {"in": "query", "name": "actual_planned_quantity_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned quantity", "title": "Actual Planned Quantity Max"}, "required": false, "description": "Maximum actual planned quantity"}, {"in": "query", "name": "fixed_planned_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Min"}, "required": false, "description": "Minimum fixed planned revenue (in project currency)"}, {"in": "query", "name": "fixed_planned_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Max"}, "required": false, "description": "Maximum fixed planned revenue (in project currency)"}, {"in": "query", "name": "fixed_planned_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Min"}, "required": false, "description": "Minimum fixed planned revenue in EUR"}, {"in": "query", "name": "fixed_planned_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Max"}, "required": false, "description": "Maximum fixed planned revenue in EUR"}, {"in": "query", "name": "fixed_planned_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Min"}, "required": false, "description": "Minimum fixed planned revenue in USD"}, {"in": "query", "name": "fixed_planned_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Max"}, "required": false, "description": "Maximum fixed planned revenue in USD"}, {"in": "query", "name": "fixed_planned_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Min"}, "required": false, "description": "Minimum fixed planned revenue in AUD"}, {"in": "query", "name": "fixed_planned_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Max"}, "required": false, "description": "Maximum fixed planned revenue in AUD"}, {"in": "query", "name": "invoiced_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue (in project currency)", "title": "Invoiced Revenue Min"}, "required": false, "description": "Minimum invoiced revenue (in project currency)"}, {"in": "query", "name": "invoiced_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue (in project currency)", "title": "Invoiced Revenue Max"}, "required": false, "description": "Maximum invoiced revenue (in project currency)"}, {"in": "query", "name": "invoiced_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Min"}, "required": false, "description": "Minimum invoiced revenue in EUR"}, {"in": "query", "name": "invoiced_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Max"}, "required": false, "description": "Maximum invoiced revenue in EUR"}, {"in": "query", "name": "invoiced_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in USD", "title": "Invoiced Revenue Usd Min"}, "required": false, "description": "Minimum invoiced revenue in USD"}, {"in": "query", "name": "invoiced_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in USD", "title": "Invoiced Revenue Usd Max"}, "required": false, "description": "Maximum invoiced revenue in USD"}, {"in": "query", "name": "invoiced_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Min"}, "required": false, "description": "Minimum invoiced revenue in AUD"}, {"in": "query", "name": "invoiced_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Max"}, "required": false, "description": "Maximum invoiced revenue in AUD"}, {"in": "query", "name": "draft_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges (in project currency)", "title": "Draft Charges Min"}, "required": false, "description": "Minimum draft charges (in project currency)"}, {"in": "query", "name": "draft_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges (in project currency)", "title": "Draft Charges Max"}, "required": false, "description": "Maximum draft charges (in project currency)"}, {"in": "query", "name": "draft_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in EUR", "title": "Draft Charges Eur Min"}, "required": false, "description": "Minimum draft charges in EUR"}, {"in": "query", "name": "draft_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in EUR", "title": "Draft Charges Eur Max"}, "required": false, "description": "Maximum draft charges in EUR"}, {"in": "query", "name": "draft_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in USD", "title": "Draft Charges Usd Min"}, "required": false, "description": "Minimum draft charges in USD"}, {"in": "query", "name": "draft_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in USD", "title": "Draft Charges Usd Max"}, "required": false, "description": "Maximum draft charges in USD"}, {"in": "query", "name": "draft_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in AUD", "title": "Draft Charges Aud Min"}, "required": false, "description": "Minimum draft charges in AUD"}, {"in": "query", "name": "draft_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in AUD", "title": "Draft Charges Aud Max"}, "required": false, "description": "Maximum draft charges in AUD"}, {"in": "query", "name": "approved_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges (in project currency)", "title": "Approved Charges Min"}, "required": false, "description": "Minimum approved charges (in project currency)"}, {"in": "query", "name": "approved_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges (in project currency)", "title": "Approved Charges Max"}, "required": false, "description": "Maximum approved charges (in project currency)"}, {"in": "query", "name": "approved_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in EUR", "title": "Approved Charges Eur Min"}, "required": false, "description": "Minimum approved charges in EUR"}, {"in": "query", "name": "approved_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in EUR", "title": "Approved Charges Eur Max"}, "required": false, "description": "Maximum approved charges in EUR"}, {"in": "query", "name": "approved_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in USD", "title": "Approved Charges Usd Min"}, "required": false, "description": "Minimum approved charges in USD"}, {"in": "query", "name": "approved_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in USD", "title": "Approved Charges Usd Max"}, "required": false, "description": "Maximum approved charges in USD"}, {"in": "query", "name": "approved_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in AUD", "title": "Approved Charges Aud Min"}, "required": false, "description": "Minimum approved charges in AUD"}, {"in": "query", "name": "approved_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in AUD", "title": "Approved Charges Aud Max"}, "required": false, "description": "Maximum approved charges in AUD"}, {"in": "query", "name": "require_po_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges (in project currency)", "title": "Require Po Charges Min"}, "required": false, "description": "Minimum require-PO charges (in project currency)"}, {"in": "query", "name": "require_po_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges (in project currency)", "title": "Require Po Charges Max"}, "required": false, "description": "Maximum require-PO charges (in project currency)"}, {"in": "query", "name": "require_po_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in EUR", "title": "Require Po Charges Eur Min"}, "required": false, "description": "Minimum require-PO charges in EUR"}, {"in": "query", "name": "require_po_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in EUR", "title": "Require Po Charges Eur Max"}, "required": false, "description": "Maximum require-PO charges in EUR"}, {"in": "query", "name": "require_po_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in USD", "title": "Require Po Charges Usd Min"}, "required": false, "description": "Minimum require-PO charges in USD"}, {"in": "query", "name": "require_po_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in USD", "title": "Require Po Charges Usd Max"}, "required": false, "description": "Maximum require-PO charges in USD"}, {"in": "query", "name": "require_po_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in AUD", "title": "Require Po Charges Aud Min"}, "required": false, "description": "Minimum require-PO charges in AUD"}, {"in": "query", "name": "require_po_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in AUD", "title": "Require Po Charges Aud Max"}, "required": false, "description": "Maximum require-PO charges in AUD"}, {"in": "query", "name": "closure_start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date start", "title": "Closure Start Date"}, "required": false, "description": "Filter by project closure date start"}, {"in": "query", "name": "closure_end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date end", "title": "Closure End Date"}, "required": false, "description": "Filter by project closure date end"}, {"in": "query", "name": "has_unresolved_comments", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by projects with unresolved comments", "title": "Has Unresolved Comments"}, "required": false, "description": "Filter by projects with unresolved comments"}, {"in": "query", "name": "page", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1, "description": "Page number for pagination", "title": "Page"}, "required": false, "description": "Page number for pagination"}, {"in": "query", "name": "page_size", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1000, "description": "Number of items per page", "title": "Page Size"}, "required": false, "description": "Number of items per page"}, {"in": "query", "name": "sort_by", "schema": {"anyOf": [{"$ref": "#/components/schemas/AccountingOverviewSortBy"}, {"type": "null"}], "description": "Field to sort by"}, "required": false, "description": "Field to sort by"}, {"in": "query", "name": "sort_order", "schema": {"anyOf": [{"enum": ["asc", "desc"], "type": "string"}, {"type": "null"}], "default": "asc", "description": "Sort order (asc or desc)", "title": "Sort Order"}, "required": false, "description": "Sort order (asc or desc)"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ProjectRevenue"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get accounting overview of revenue with filtering and pagination.\n\nArgs:\n request: The HTTP request object.\n params: Query parameters for filtering and pagination.\n\nSupports filtering by:\n- search: Search by project code (partial matching)\n- clients: Filter by client names (comma-separated)\n- pm: Filter by project managers (comma-separated)\n- region: Filter by regions (comma-separated)\n- country: Filter by countries (comma-separated)\n- start_date/end_date: Date range filtering\n- project_status: Filter by core project status (comma-separated)\n- service_code: Filter by billable service code (comma-separated)\n- Revenue range filters (min/max): total_revenue, added_to_invoice_revenue, actual_planned_revenue (all with _eur/_usd/_aud variants)\n- Quantity range filters (min/max): total_quantity, actual_planned_quantity\n\nPagination is handled automatically with page/page_size parameters.\nResponse headers include Page, Page-Size, and Total-Count.", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/overview/summary": {"get": {"operationId": "accounting_api_v2_get_accounting_overview_summary", "summary": "Get Accounting Overview Summary", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "required": false, "description": "Start date for filtering charges"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}, "required": false, "description": "End date for filtering charges"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by project code (partial matching)", "title": "Search"}, "required": false, "description": "Search by project code (partial matching)"}, {"in": "query", "name": "clients", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client names (comma-separated)", "title": "Clients"}, "required": false, "description": "Filter by client names (comma-separated)"}, {"in": "query", "name": "pm", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project managers (comma-separated)", "title": "Pm"}, "required": false, "description": "Filter by project managers (comma-separated)"}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "required": false, "description": "Filter by regions (comma-separated)"}, {"in": "query", "name": "country", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by countries (comma-separated)", "title": "Country"}, "required": false, "description": "Filter by countries (comma-separated)"}, {"in": "query", "name": "project_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by core project status (comma-separated)", "title": "Project Status"}, "required": false, "description": "Filter by core project status (comma-separated)"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billable service code (comma-separated)", "title": "Service Code"}, "required": false, "description": "Filter by billable service code (comma-separated)"}, {"in": "query", "name": "service_unit_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service unit type (comma-separated)", "title": "Service Unit Type"}, "required": false, "description": "Filter by service unit type (comma-separated)"}, {"in": "query", "name": "robot_set", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robot set (comma-separated)", "title": "Robot Set"}, "required": false, "description": "Filter by robot set (comma-separated)"}, {"in": "query", "name": "total_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue (in project currency)", "title": "Total Revenue Min"}, "required": false, "description": "Minimum total revenue (in project currency)"}, {"in": "query", "name": "total_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue (in project currency)", "title": "Total Revenue Max"}, "required": false, "description": "Maximum total revenue (in project currency)"}, {"in": "query", "name": "total_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in EUR", "title": "Total Revenue Eur Min"}, "required": false, "description": "Minimum total revenue in EUR"}, {"in": "query", "name": "total_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in EUR", "title": "Total Revenue Eur Max"}, "required": false, "description": "Maximum total revenue in EUR"}, {"in": "query", "name": "total_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in USD", "title": "Total Revenue Usd Min"}, "required": false, "description": "Minimum total revenue in USD"}, {"in": "query", "name": "total_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in USD", "title": "Total Revenue Usd Max"}, "required": false, "description": "Maximum total revenue in USD"}, {"in": "query", "name": "total_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in AUD", "title": "Total Revenue Aud Min"}, "required": false, "description": "Minimum total revenue in AUD"}, {"in": "query", "name": "total_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in AUD", "title": "Total Revenue Aud Max"}, "required": false, "description": "Maximum total revenue in AUD"}, {"in": "query", "name": "added_to_invoice_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Min"}, "required": false, "description": "Minimum added to invoice revenue (in project currency)"}, {"in": "query", "name": "added_to_invoice_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Max"}, "required": false, "description": "Maximum added to invoice revenue (in project currency)"}, {"in": "query", "name": "added_to_invoice_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Min"}, "required": false, "description": "Minimum added to invoice revenue in EUR"}, {"in": "query", "name": "added_to_invoice_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Max"}, "required": false, "description": "Maximum added to invoice revenue in EUR"}, {"in": "query", "name": "added_to_invoice_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Min"}, "required": false, "description": "Minimum added to invoice revenue in USD"}, {"in": "query", "name": "added_to_invoice_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Max"}, "required": false, "description": "Maximum added to invoice revenue in USD"}, {"in": "query", "name": "added_to_invoice_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Min"}, "required": false, "description": "Minimum added to invoice revenue in AUD"}, {"in": "query", "name": "added_to_invoice_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Max"}, "required": false, "description": "Maximum added to invoice revenue in AUD"}, {"in": "query", "name": "actual_planned_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Min"}, "required": false, "description": "Minimum actual planned revenue (in project currency)"}, {"in": "query", "name": "actual_planned_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Max"}, "required": false, "description": "Maximum actual planned revenue (in project currency)"}, {"in": "query", "name": "actual_planned_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Min"}, "required": false, "description": "Minimum actual planned revenue in EUR"}, {"in": "query", "name": "actual_planned_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Max"}, "required": false, "description": "Maximum actual planned revenue in EUR"}, {"in": "query", "name": "actual_planned_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Min"}, "required": false, "description": "Minimum actual planned revenue in USD"}, {"in": "query", "name": "actual_planned_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Max"}, "required": false, "description": "Maximum actual planned revenue in USD"}, {"in": "query", "name": "actual_planned_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Min"}, "required": false, "description": "Minimum actual planned revenue in AUD"}, {"in": "query", "name": "actual_planned_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Max"}, "required": false, "description": "Maximum actual planned revenue in AUD"}, {"in": "query", "name": "total_quantity_min", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum total quantity", "title": "Total Quantity Min"}, "required": false, "description": "Minimum total quantity"}, {"in": "query", "name": "total_quantity_max", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum total quantity", "title": "Total Quantity Max"}, "required": false, "description": "Maximum total quantity"}, {"in": "query", "name": "actual_planned_quantity_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned quantity", "title": "Actual Planned Quantity Min"}, "required": false, "description": "Minimum actual planned quantity"}, {"in": "query", "name": "actual_planned_quantity_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned quantity", "title": "Actual Planned Quantity Max"}, "required": false, "description": "Maximum actual planned quantity"}, {"in": "query", "name": "fixed_planned_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Min"}, "required": false, "description": "Minimum fixed planned revenue (in project currency)"}, {"in": "query", "name": "fixed_planned_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Max"}, "required": false, "description": "Maximum fixed planned revenue (in project currency)"}, {"in": "query", "name": "fixed_planned_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Min"}, "required": false, "description": "Minimum fixed planned revenue in EUR"}, {"in": "query", "name": "fixed_planned_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Max"}, "required": false, "description": "Maximum fixed planned revenue in EUR"}, {"in": "query", "name": "fixed_planned_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Min"}, "required": false, "description": "Minimum fixed planned revenue in USD"}, {"in": "query", "name": "fixed_planned_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Max"}, "required": false, "description": "Maximum fixed planned revenue in USD"}, {"in": "query", "name": "fixed_planned_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Min"}, "required": false, "description": "Minimum fixed planned revenue in AUD"}, {"in": "query", "name": "fixed_planned_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Max"}, "required": false, "description": "Maximum fixed planned revenue in AUD"}, {"in": "query", "name": "invoiced_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue (in project currency)", "title": "Invoiced Revenue Min"}, "required": false, "description": "Minimum invoiced revenue (in project currency)"}, {"in": "query", "name": "invoiced_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue (in project currency)", "title": "Invoiced Revenue Max"}, "required": false, "description": "Maximum invoiced revenue (in project currency)"}, {"in": "query", "name": "invoiced_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Min"}, "required": false, "description": "Minimum invoiced revenue in EUR"}, {"in": "query", "name": "invoiced_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Max"}, "required": false, "description": "Maximum invoiced revenue in EUR"}, {"in": "query", "name": "invoiced_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in USD", "title": "Invoiced Revenue Usd Min"}, "required": false, "description": "Minimum invoiced revenue in USD"}, {"in": "query", "name": "invoiced_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in USD", "title": "Invoiced Revenue Usd Max"}, "required": false, "description": "Maximum invoiced revenue in USD"}, {"in": "query", "name": "invoiced_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Min"}, "required": false, "description": "Minimum invoiced revenue in AUD"}, {"in": "query", "name": "invoiced_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Max"}, "required": false, "description": "Maximum invoiced revenue in AUD"}, {"in": "query", "name": "draft_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges (in project currency)", "title": "Draft Charges Min"}, "required": false, "description": "Minimum draft charges (in project currency)"}, {"in": "query", "name": "draft_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges (in project currency)", "title": "Draft Charges Max"}, "required": false, "description": "Maximum draft charges (in project currency)"}, {"in": "query", "name": "draft_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in EUR", "title": "Draft Charges Eur Min"}, "required": false, "description": "Minimum draft charges in EUR"}, {"in": "query", "name": "draft_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in EUR", "title": "Draft Charges Eur Max"}, "required": false, "description": "Maximum draft charges in EUR"}, {"in": "query", "name": "draft_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in USD", "title": "Draft Charges Usd Min"}, "required": false, "description": "Minimum draft charges in USD"}, {"in": "query", "name": "draft_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in USD", "title": "Draft Charges Usd Max"}, "required": false, "description": "Maximum draft charges in USD"}, {"in": "query", "name": "draft_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in AUD", "title": "Draft Charges Aud Min"}, "required": false, "description": "Minimum draft charges in AUD"}, {"in": "query", "name": "draft_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in AUD", "title": "Draft Charges Aud Max"}, "required": false, "description": "Maximum draft charges in AUD"}, {"in": "query", "name": "approved_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges (in project currency)", "title": "Approved Charges Min"}, "required": false, "description": "Minimum approved charges (in project currency)"}, {"in": "query", "name": "approved_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges (in project currency)", "title": "Approved Charges Max"}, "required": false, "description": "Maximum approved charges (in project currency)"}, {"in": "query", "name": "approved_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in EUR", "title": "Approved Charges Eur Min"}, "required": false, "description": "Minimum approved charges in EUR"}, {"in": "query", "name": "approved_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in EUR", "title": "Approved Charges Eur Max"}, "required": false, "description": "Maximum approved charges in EUR"}, {"in": "query", "name": "approved_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in USD", "title": "Approved Charges Usd Min"}, "required": false, "description": "Minimum approved charges in USD"}, {"in": "query", "name": "approved_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in USD", "title": "Approved Charges Usd Max"}, "required": false, "description": "Maximum approved charges in USD"}, {"in": "query", "name": "approved_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in AUD", "title": "Approved Charges Aud Min"}, "required": false, "description": "Minimum approved charges in AUD"}, {"in": "query", "name": "approved_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in AUD", "title": "Approved Charges Aud Max"}, "required": false, "description": "Maximum approved charges in AUD"}, {"in": "query", "name": "require_po_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges (in project currency)", "title": "Require Po Charges Min"}, "required": false, "description": "Minimum require-PO charges (in project currency)"}, {"in": "query", "name": "require_po_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges (in project currency)", "title": "Require Po Charges Max"}, "required": false, "description": "Maximum require-PO charges (in project currency)"}, {"in": "query", "name": "require_po_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in EUR", "title": "Require Po Charges Eur Min"}, "required": false, "description": "Minimum require-PO charges in EUR"}, {"in": "query", "name": "require_po_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in EUR", "title": "Require Po Charges Eur Max"}, "required": false, "description": "Maximum require-PO charges in EUR"}, {"in": "query", "name": "require_po_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in USD", "title": "Require Po Charges Usd Min"}, "required": false, "description": "Minimum require-PO charges in USD"}, {"in": "query", "name": "require_po_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in USD", "title": "Require Po Charges Usd Max"}, "required": false, "description": "Maximum require-PO charges in USD"}, {"in": "query", "name": "require_po_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in AUD", "title": "Require Po Charges Aud Min"}, "required": false, "description": "Minimum require-PO charges in AUD"}, {"in": "query", "name": "require_po_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in AUD", "title": "Require Po Charges Aud Max"}, "required": false, "description": "Maximum require-PO charges in AUD"}, {"in": "query", "name": "closure_start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date start", "title": "Closure Start Date"}, "required": false, "description": "Filter by project closure date start"}, {"in": "query", "name": "closure_end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date end", "title": "Closure End Date"}, "required": false, "description": "Filter by project closure date end"}, {"in": "query", "name": "has_unresolved_comments", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by projects with unresolved comments", "title": "Has Unresolved Comments"}, "required": false, "description": "Filter by projects with unresolved comments"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountingOverviewSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get aggregated summary of accounting overview data with the same filtering as /overview/.\n\nArgs:\n request: The HTTP request object.\n params: Query parameters for filtering (same as overview endpoint except pagination).\n\nReturns aggregated data:\n- client_count: Total number of unique clients\n- project_count: Total number of projects (same as total-count in /overview/)\n- total_revenue_eur/usd/aud: Summed revenue by currency\n- added_to_invoice_revenue_eur/usd/aud: Summed added to invoice revenue by currency\n- actual_planned_revenue_eur/usd/aud: Summed planned revenue by currency\n- fixed_planned_revenue_eur/usd/aud: Summed fixed planned revenue by currency\n\nSupports the same filtering as /overview/:\n- search: Search by project code (partial matching)\n- clients: Filter by client names (comma-separated)\n- pm: Filter by project managers (comma-separated)\n- region: Filter by regions (comma-separated)\n- country: Filter by countries (comma-separated)\n- start_date/end_date: Date range filtering\n- project_status: Filter by core project status (comma-separated)\n- service_code: Filter by billable service code (comma-separated)\n- Revenue range filters (min/max): total_revenue, added_to_invoice_revenue, actual_planned_revenue, fixed_planned_revenue (all with _eur/_usd/_aud variants)\n- Quantity range filters (min/max): total_quantity, actual_planned_quantity\n- Closure date filters: closure_start_date, closure_end_date", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/overview/filters": {"get": {"operationId": "accounting_api_v2_get_accounting_overview_filters", "summary": "Get Accounting Overview Filters", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "required": false, "description": "Start date for filtering charges"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}, "required": false, "description": "End date for filtering charges"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountingOverviewFilters"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get available filter values for accounting overview data.\n\nArgs:\n request: The HTTP request object.\n params: Query parameters for date range filtering (optional).\n\nReturns unique values for filtering:\n- clients: List of all unique client names\n- pm: List of all unique project managers\n- regions: List of all unique regions (continents)\n- countries: List of all unique countries\n- project_status: List of all unique core project statuses\n- service_code: List of all unique billable service codes\n\nSupports optional date range filtering:\n- start_date/end_date: Limit results to projects within date range", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/overview/export": {"get": {"operationId": "accounting_api_v2_export_accounting_overview_to_excel", "summary": "Export Accounting Overview To Excel", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "required": false, "description": "Start date for filtering charges"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}, "required": false, "description": "End date for filtering charges"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by project code (partial matching)", "title": "Search"}, "required": false, "description": "Search by project code (partial matching)"}, {"in": "query", "name": "clients", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client names (comma-separated)", "title": "Clients"}, "required": false, "description": "Filter by client names (comma-separated)"}, {"in": "query", "name": "pm", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project managers (comma-separated)", "title": "Pm"}, "required": false, "description": "Filter by project managers (comma-separated)"}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "required": false, "description": "Filter by regions (comma-separated)"}, {"in": "query", "name": "country", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by countries (comma-separated)", "title": "Country"}, "required": false, "description": "Filter by countries (comma-separated)"}, {"in": "query", "name": "project_status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by core project status (comma-separated)", "title": "Project Status"}, "required": false, "description": "Filter by core project status (comma-separated)"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billable service code (comma-separated)", "title": "Service Code"}, "required": false, "description": "Filter by billable service code (comma-separated)"}, {"in": "query", "name": "service_unit_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service unit type (comma-separated)", "title": "Service Unit Type"}, "required": false, "description": "Filter by service unit type (comma-separated)"}, {"in": "query", "name": "robot_set", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robot set (comma-separated)", "title": "Robot Set"}, "required": false, "description": "Filter by robot set (comma-separated)"}, {"in": "query", "name": "total_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue (in project currency)", "title": "Total Revenue Min"}, "required": false, "description": "Minimum total revenue (in project currency)"}, {"in": "query", "name": "total_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue (in project currency)", "title": "Total Revenue Max"}, "required": false, "description": "Maximum total revenue (in project currency)"}, {"in": "query", "name": "total_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in EUR", "title": "Total Revenue Eur Min"}, "required": false, "description": "Minimum total revenue in EUR"}, {"in": "query", "name": "total_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in EUR", "title": "Total Revenue Eur Max"}, "required": false, "description": "Maximum total revenue in EUR"}, {"in": "query", "name": "total_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in USD", "title": "Total Revenue Usd Min"}, "required": false, "description": "Minimum total revenue in USD"}, {"in": "query", "name": "total_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in USD", "title": "Total Revenue Usd Max"}, "required": false, "description": "Maximum total revenue in USD"}, {"in": "query", "name": "total_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in AUD", "title": "Total Revenue Aud Min"}, "required": false, "description": "Minimum total revenue in AUD"}, {"in": "query", "name": "total_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in AUD", "title": "Total Revenue Aud Max"}, "required": false, "description": "Maximum total revenue in AUD"}, {"in": "query", "name": "added_to_invoice_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Min"}, "required": false, "description": "Minimum added to invoice revenue (in project currency)"}, {"in": "query", "name": "added_to_invoice_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Max"}, "required": false, "description": "Maximum added to invoice revenue (in project currency)"}, {"in": "query", "name": "added_to_invoice_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Min"}, "required": false, "description": "Minimum added to invoice revenue in EUR"}, {"in": "query", "name": "added_to_invoice_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Max"}, "required": false, "description": "Maximum added to invoice revenue in EUR"}, {"in": "query", "name": "added_to_invoice_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Min"}, "required": false, "description": "Minimum added to invoice revenue in USD"}, {"in": "query", "name": "added_to_invoice_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Max"}, "required": false, "description": "Maximum added to invoice revenue in USD"}, {"in": "query", "name": "added_to_invoice_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Min"}, "required": false, "description": "Minimum added to invoice revenue in AUD"}, {"in": "query", "name": "added_to_invoice_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Max"}, "required": false, "description": "Maximum added to invoice revenue in AUD"}, {"in": "query", "name": "actual_planned_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Min"}, "required": false, "description": "Minimum actual planned revenue (in project currency)"}, {"in": "query", "name": "actual_planned_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Max"}, "required": false, "description": "Maximum actual planned revenue (in project currency)"}, {"in": "query", "name": "actual_planned_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Min"}, "required": false, "description": "Minimum actual planned revenue in EUR"}, {"in": "query", "name": "actual_planned_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Max"}, "required": false, "description": "Maximum actual planned revenue in EUR"}, {"in": "query", "name": "actual_planned_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Min"}, "required": false, "description": "Minimum actual planned revenue in USD"}, {"in": "query", "name": "actual_planned_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Max"}, "required": false, "description": "Maximum actual planned revenue in USD"}, {"in": "query", "name": "actual_planned_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Min"}, "required": false, "description": "Minimum actual planned revenue in AUD"}, {"in": "query", "name": "actual_planned_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Max"}, "required": false, "description": "Maximum actual planned revenue in AUD"}, {"in": "query", "name": "total_quantity_min", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum total quantity", "title": "Total Quantity Min"}, "required": false, "description": "Minimum total quantity"}, {"in": "query", "name": "total_quantity_max", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum total quantity", "title": "Total Quantity Max"}, "required": false, "description": "Maximum total quantity"}, {"in": "query", "name": "actual_planned_quantity_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned quantity", "title": "Actual Planned Quantity Min"}, "required": false, "description": "Minimum actual planned quantity"}, {"in": "query", "name": "actual_planned_quantity_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned quantity", "title": "Actual Planned Quantity Max"}, "required": false, "description": "Maximum actual planned quantity"}, {"in": "query", "name": "fixed_planned_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Min"}, "required": false, "description": "Minimum fixed planned revenue (in project currency)"}, {"in": "query", "name": "fixed_planned_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Max"}, "required": false, "description": "Maximum fixed planned revenue (in project currency)"}, {"in": "query", "name": "fixed_planned_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Min"}, "required": false, "description": "Minimum fixed planned revenue in EUR"}, {"in": "query", "name": "fixed_planned_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Max"}, "required": false, "description": "Maximum fixed planned revenue in EUR"}, {"in": "query", "name": "fixed_planned_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Min"}, "required": false, "description": "Minimum fixed planned revenue in USD"}, {"in": "query", "name": "fixed_planned_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Max"}, "required": false, "description": "Maximum fixed planned revenue in USD"}, {"in": "query", "name": "fixed_planned_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Min"}, "required": false, "description": "Minimum fixed planned revenue in AUD"}, {"in": "query", "name": "fixed_planned_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Max"}, "required": false, "description": "Maximum fixed planned revenue in AUD"}, {"in": "query", "name": "invoiced_revenue_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue (in project currency)", "title": "Invoiced Revenue Min"}, "required": false, "description": "Minimum invoiced revenue (in project currency)"}, {"in": "query", "name": "invoiced_revenue_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue (in project currency)", "title": "Invoiced Revenue Max"}, "required": false, "description": "Maximum invoiced revenue (in project currency)"}, {"in": "query", "name": "invoiced_revenue_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Min"}, "required": false, "description": "Minimum invoiced revenue in EUR"}, {"in": "query", "name": "invoiced_revenue_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Max"}, "required": false, "description": "Maximum invoiced revenue in EUR"}, {"in": "query", "name": "invoiced_revenue_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in USD", "title": "Invoiced Revenue Usd Min"}, "required": false, "description": "Minimum invoiced revenue in USD"}, {"in": "query", "name": "invoiced_revenue_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in USD", "title": "Invoiced Revenue Usd Max"}, "required": false, "description": "Maximum invoiced revenue in USD"}, {"in": "query", "name": "invoiced_revenue_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Min"}, "required": false, "description": "Minimum invoiced revenue in AUD"}, {"in": "query", "name": "invoiced_revenue_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Max"}, "required": false, "description": "Maximum invoiced revenue in AUD"}, {"in": "query", "name": "draft_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges (in project currency)", "title": "Draft Charges Min"}, "required": false, "description": "Minimum draft charges (in project currency)"}, {"in": "query", "name": "draft_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges (in project currency)", "title": "Draft Charges Max"}, "required": false, "description": "Maximum draft charges (in project currency)"}, {"in": "query", "name": "draft_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in EUR", "title": "Draft Charges Eur Min"}, "required": false, "description": "Minimum draft charges in EUR"}, {"in": "query", "name": "draft_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in EUR", "title": "Draft Charges Eur Max"}, "required": false, "description": "Maximum draft charges in EUR"}, {"in": "query", "name": "draft_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in USD", "title": "Draft Charges Usd Min"}, "required": false, "description": "Minimum draft charges in USD"}, {"in": "query", "name": "draft_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in USD", "title": "Draft Charges Usd Max"}, "required": false, "description": "Maximum draft charges in USD"}, {"in": "query", "name": "draft_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in AUD", "title": "Draft Charges Aud Min"}, "required": false, "description": "Minimum draft charges in AUD"}, {"in": "query", "name": "draft_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in AUD", "title": "Draft Charges Aud Max"}, "required": false, "description": "Maximum draft charges in AUD"}, {"in": "query", "name": "approved_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges (in project currency)", "title": "Approved Charges Min"}, "required": false, "description": "Minimum approved charges (in project currency)"}, {"in": "query", "name": "approved_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges (in project currency)", "title": "Approved Charges Max"}, "required": false, "description": "Maximum approved charges (in project currency)"}, {"in": "query", "name": "approved_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in EUR", "title": "Approved Charges Eur Min"}, "required": false, "description": "Minimum approved charges in EUR"}, {"in": "query", "name": "approved_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in EUR", "title": "Approved Charges Eur Max"}, "required": false, "description": "Maximum approved charges in EUR"}, {"in": "query", "name": "approved_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in USD", "title": "Approved Charges Usd Min"}, "required": false, "description": "Minimum approved charges in USD"}, {"in": "query", "name": "approved_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in USD", "title": "Approved Charges Usd Max"}, "required": false, "description": "Maximum approved charges in USD"}, {"in": "query", "name": "approved_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in AUD", "title": "Approved Charges Aud Min"}, "required": false, "description": "Minimum approved charges in AUD"}, {"in": "query", "name": "approved_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in AUD", "title": "Approved Charges Aud Max"}, "required": false, "description": "Maximum approved charges in AUD"}, {"in": "query", "name": "require_po_charges_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges (in project currency)", "title": "Require Po Charges Min"}, "required": false, "description": "Minimum require-PO charges (in project currency)"}, {"in": "query", "name": "require_po_charges_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges (in project currency)", "title": "Require Po Charges Max"}, "required": false, "description": "Maximum require-PO charges (in project currency)"}, {"in": "query", "name": "require_po_charges_eur_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in EUR", "title": "Require Po Charges Eur Min"}, "required": false, "description": "Minimum require-PO charges in EUR"}, {"in": "query", "name": "require_po_charges_eur_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in EUR", "title": "Require Po Charges Eur Max"}, "required": false, "description": "Maximum require-PO charges in EUR"}, {"in": "query", "name": "require_po_charges_usd_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in USD", "title": "Require Po Charges Usd Min"}, "required": false, "description": "Minimum require-PO charges in USD"}, {"in": "query", "name": "require_po_charges_usd_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in USD", "title": "Require Po Charges Usd Max"}, "required": false, "description": "Maximum require-PO charges in USD"}, {"in": "query", "name": "require_po_charges_aud_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in AUD", "title": "Require Po Charges Aud Min"}, "required": false, "description": "Minimum require-PO charges in AUD"}, {"in": "query", "name": "require_po_charges_aud_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in AUD", "title": "Require Po Charges Aud Max"}, "required": false, "description": "Maximum require-PO charges in AUD"}, {"in": "query", "name": "closure_start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date start", "title": "Closure Start Date"}, "required": false, "description": "Filter by project closure date start"}, {"in": "query", "name": "closure_end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date end", "title": "Closure End Date"}, "required": false, "description": "Filter by project closure date end"}, {"in": "query", "name": "has_unresolved_comments", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by projects with unresolved comments", "title": "Has Unresolved Comments"}, "required": false, "description": "Filter by projects with unresolved comments"}, {"in": "query", "name": "page", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1, "description": "Page number for pagination", "title": "Page"}, "required": false, "description": "Page number for pagination"}, {"in": "query", "name": "page_size", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1000, "description": "Number of items per page", "title": "Page Size"}, "required": false, "description": "Number of items per page"}, {"in": "query", "name": "sort_by", "schema": {"anyOf": [{"$ref": "#/components/schemas/AccountingOverviewSortBy"}, {"type": "null"}], "description": "Field to sort by"}, "required": false, "description": "Field to sort by"}, {"in": "query", "name": "sort_order", "schema": {"anyOf": [{"enum": ["asc", "desc"], "type": "string"}, {"type": "null"}], "default": "asc", "description": "Sort order (asc or desc)", "title": "Sort Order"}, "required": false, "description": "Sort order (asc or desc)"}], "responses": {"200": {"description": "OK"}}, "description": "Export accounting overview data to Excel file.\n\nArgs:\n request: The HTTP request object.\n params: Query parameters for filtering (same as /overview/ endpoint).\n\nSupports the same filtering as /overview/ endpoint:\n- search: Search by project code (partial matching)\n- clients: Filter by client names (comma-separated)\n- pm: Filter by project managers (comma-separated)\n- region: Filter by regions (comma-separated)\n- country: Filter by countries (comma-separated)\n- start_date/end_date: Date range filtering\n- project_status: Filter by core project status (comma-separated)\n\nReturns all matching records (no pagination).\nResponse is an Excel file with filename: accounting_overview_{YYYY-MM-DD}.xlsx", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/missing-charges-tracker": {"get": {"operationId": "accounting_api_v2_get_missing_charges_tracker", "summary": "Get Missing Charges Tracker", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search term for project code or set name", "title": "Search"}, "required": false, "description": "Search term for project code or set name"}, {"in": "query", "name": "reason_filter", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by reason type: 'charge-entry', 'sales-order-missing', or None for all.", "title": "Reason Filter"}, "required": false, "description": "Filter by reason type: 'charge-entry', 'sales-order-missing', or None for all."}, {"in": "query", "name": "project_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project codes to filter by", "title": "Project Codes"}, "required": false, "description": "Comma-separated list of project codes to filter by"}, {"in": "query", "name": "set_names", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of set names to filter by", "title": "Set Names"}, "required": false, "description": "Comma-separated list of set names to filter by"}, {"in": "query", "name": "project_managers", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project manager names to filter by", "title": "Project Managers"}, "required": false, "description": "Comma-separated list of project manager names to filter by"}, {"in": "query", "name": "delay_days_min", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum delay days filter", "title": "Delay Days Min"}, "required": false, "description": "Minimum delay days filter"}, {"in": "query", "name": "delay_days_max", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum delay days filter", "title": "Delay Days Max"}, "required": false, "description": "Maximum delay days filter"}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates from this date (inclusive)", "title": "Date From"}, "required": false, "description": "Filter work dates from this date (inclusive)"}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates to this date (inclusive)", "title": "Date To"}, "required": false, "description": "Filter work dates to this date (inclusive)"}, {"in": "query", "name": "sort_field", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Field to sort by: projectCode, setName, delayDays, workDate, suggestedAmount, reasons, comment", "title": "Sort Field"}, "required": false, "description": "Field to sort by: projectCode, setName, delayDays, workDate, suggestedAmount, reasons, comment"}, {"in": "query", "name": "sort_order", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort order: 'ascend' or 'descend'", "title": "Sort Order"}, "required": false, "description": "Sort order: 'ascend' or 'descend'"}, {"in": "query", "name": "currency", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "EUR", "description": "Display currency for approximate amounts: EUR, USD, or AUD", "title": "Currency"}, "required": false, "description": "Display currency for approximate amounts: EUR, USD, or AUD"}, {"in": "query", "name": "exclude_sundays", "schema": {"default": false, "description": "If True, exclude Sunday records from results.", "title": "Exclude Sundays", "type": "boolean"}, "required": false, "description": "If True, exclude Sunday records from results."}, {"in": "query", "name": "hide_with_comments", "schema": {"default": false, "description": "If True, exclude records that have a comment.", "title": "Hide With Comments", "type": "boolean"}, "required": false, "description": "If True, exclude records that have a comment."}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 10, "description": "Items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Items per page"}, {"in": "query", "name": "use_cache", "schema": {"default": true, "description": "If True, read from cache. If False, fetch live data.", "title": "Use Cache", "type": "boolean"}, "required": false, "description": "If True, read from cache. If False, fetch live data."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MissingChargesTrackerResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get missing charges tracker data for all projects.\n\nReturns projects with missing charge entries,\norganized by robot set with delay calculations.\n\nBy default reads from cache (fast). Set use_cache=false to fetch live data.\n\nData sources:\n- Cache: Local database table (fast, updated hourly)\n- Live: Platform API + NetSuite API (slow, real-time)\n\nArgs:\n request: HTTP request object.\n params: Query parameters including pagination, search, filters.\n\nQuery params:\n- page: Page number (default 1).\n- page_size: Items per page (default 10).\n- search: Search term for project code or set name (optional).\n- reason_filter: Filter by reason type: 'charge-entry' or 'sales-order-missing' (optional).\n- use_cache: If True (default), read from cache. If False, fetch live data.\n\nReturns:\n MissingChargesTrackerResponse with summary stats and paginated items.", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/missing-charges-tracker/sync": {"post": {"operationId": "accounting_api_v2_sync_missing_charges_tracker", "summary": "Sync Missing Charges Tracker", "parameters": [{"in": "query", "name": "days_back", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Days Back"}, "required": false}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Date From"}, "required": false}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Date To"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MissingChargesSyncResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Manually trigger sync of missing charges data to cache.\n\nFetches fresh data from Platform and NetSuite APIs, then updates\nthe local cache table. Use this for manual refresh.\n\nArgs:\n days_back: Number of days to look back (default: covers this and last month, max 180).\n date_from: Optional start date for syncing (inclusive).\n date_to: Optional end date for syncing (inclusive).\n\nReturns:\n Sync statistics (records synced, duration, etc.).", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/missing-charges-tracker/status": {"get": {"operationId": "accounting_api_v2_get_missing_charges_cache_status", "summary": "Get Missing Charges Cache Status", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MissingChargesCacheStatus"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get cache status for missing charges tracker.\n\nReturns:\n Cache statistics (record count, last sync time, etc.).", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/charges/bulk-mark-pm-review": {"post": {"operationId": "accounting_api_v2_bulk_mark_charges_pm_review", "summary": "Bulk Mark Charges Pm Review", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkReviewResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Mark charges as queued for PM review (draft-charges heads-up step).\n\nPushes NSChargeStatusEnum.PENDING_PM_REVIEW to NetSuite for each charge,\nthen mirrors the value locally.", "tags": ["accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkReview"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/charges/bulk-mark-customer-review": {"post": {"operationId": "accounting_api_v2_bulk_mark_charges_customer_review", "summary": "Bulk Mark Charges Customer Review", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkReviewResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Mark charges as included in a sent client statement (draft-charges client send).", "tags": ["accounting"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChargeBulkReview"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/netsuite-local-sync": {"post": {"operationId": "accounting_api_v2_trigger_netsuite_local_sync", "summary": "Trigger Netsuite Local Sync", "parameters": [{"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Id"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NetSuiteLocalSyncResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Manually trigger sync of NetSuite data into local DB.\n\nFetches SOs, line items and charges from NetSuite and upserts them into\nthe local accounting tables. Pass project_id to sync a single project,\nor omit to sync all projects with so_created=True.", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/missing-charges-tracker/export": {"get": {"operationId": "accounting_api_v2_export_missing_charges_tracker", "summary": "Export Missing Charges Tracker", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search term for project code or set name", "title": "Search"}, "required": false, "description": "Search term for project code or set name"}, {"in": "query", "name": "reason_filter", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by reason type: 'charge-entry', 'sales-order-missing', or None for all.", "title": "Reason Filter"}, "required": false, "description": "Filter by reason type: 'charge-entry', 'sales-order-missing', or None for all."}, {"in": "query", "name": "project_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project codes to filter by", "title": "Project Codes"}, "required": false, "description": "Comma-separated list of project codes to filter by"}, {"in": "query", "name": "set_names", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of set names to filter by", "title": "Set Names"}, "required": false, "description": "Comma-separated list of set names to filter by"}, {"in": "query", "name": "project_managers", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project manager names to filter by", "title": "Project Managers"}, "required": false, "description": "Comma-separated list of project manager names to filter by"}, {"in": "query", "name": "delay_days_min", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum delay days filter", "title": "Delay Days Min"}, "required": false, "description": "Minimum delay days filter"}, {"in": "query", "name": "delay_days_max", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum delay days filter", "title": "Delay Days Max"}, "required": false, "description": "Maximum delay days filter"}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates from this date (inclusive)", "title": "Date From"}, "required": false, "description": "Filter work dates from this date (inclusive)"}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates to this date (inclusive)", "title": "Date To"}, "required": false, "description": "Filter work dates to this date (inclusive)"}, {"in": "query", "name": "sort_field", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Field to sort by: projectCode, setName, delayDays, workDate, suggestedAmount, reasons, comment", "title": "Sort Field"}, "required": false, "description": "Field to sort by: projectCode, setName, delayDays, workDate, suggestedAmount, reasons, comment"}, {"in": "query", "name": "sort_order", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort order: 'ascend' or 'descend'", "title": "Sort Order"}, "required": false, "description": "Sort order: 'ascend' or 'descend'"}, {"in": "query", "name": "currency", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "EUR", "description": "Display currency for approximate amounts: EUR, USD, or AUD", "title": "Currency"}, "required": false, "description": "Display currency for approximate amounts: EUR, USD, or AUD"}, {"in": "query", "name": "exclude_sundays", "schema": {"default": false, "description": "If True, exclude Sunday records from results.", "title": "Exclude Sundays", "type": "boolean"}, "required": false, "description": "If True, exclude Sunday records from results."}, {"in": "query", "name": "hide_with_comments", "schema": {"default": false, "description": "If True, exclude records that have a comment.", "title": "Hide With Comments", "type": "boolean"}, "required": false, "description": "If True, exclude records that have a comment."}], "responses": {"200": {"description": "OK"}}, "description": "Export missing charges tracker data to Excel file.\n\nReturns all records (no pagination) with current filters applied.\n\nArgs:\n request: HTTP request object.\n params: Export filters for missing charges tracker data.\n\nReturns:\n Excel file with all matching records.", "tags": ["accounting"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v1/netsuite-departments": {"get": {"operationId": "list_netsuite_departments", "summary": "List NetSuite Departments", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by department name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by department name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "netsuite_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by NetSuite department ID", "title": "Netsuite Id"}, "required": false, "description": "Filter by NetSuite department ID"}, {"in": "query", "name": "is_inactive", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by the NetSuite inactive flag; omit to get active and inactive departments", "title": "Is Inactive"}, "required": false, "description": "Filter by the NetSuite inactive flag; omit to get active and inactive departments"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NetSuiteDepartmentResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["accounting.netsuite-departments"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/sales-orders": {"get": {"operationId": "list_sales_orders", "summary": "List Sales Orders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "required": false, "description": "Search (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "required": false, "description": "Filter by customer ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesOrderResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["accounting.sales-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_sales_order", "summary": "Create Sales Order", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderResponse"}}}}}, "description": "Create a new item.", "tags": ["accounting.sales-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/sales-orders/{id}": {"get": {"operationId": "get_sales_order", "summary": "Get Sales Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["accounting.sales-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_sales_order", "summary": "Update Sales Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderResponse"}}}}}, "description": "Update an item.", "tags": ["accounting.sales-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_sales_order", "summary": "Delete Sales Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["accounting.sales-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/sales-order-lines": {"get": {"operationId": "list_sales_order_lines", "summary": "List Sales Order Lines", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "required": false, "description": "Search (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "sales_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sales order ID", "title": "Sales Order Id"}, "required": false, "description": "Filter by sales order ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesOrderLineResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["accounting.sales-order-lines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_sales_order_line", "summary": "Create Sales Order Line", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderLineResponse"}}}}}, "description": "Create a new item.", "tags": ["accounting.sales-order-lines"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderLineCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/sales-order-lines/{id}": {"get": {"operationId": "get_sales_order_line", "summary": "Get Sales Order Line", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderLineResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["accounting.sales-order-lines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_sales_order_line", "summary": "Update Sales Order Line", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderLineResponse"}}}}}, "description": "Update an item.", "tags": ["accounting.sales-order-lines"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesOrderLineUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_sales_order_line", "summary": "Delete Sales Order Line", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["accounting.sales-order-lines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/sales-invoices": {"get": {"operationId": "list_sales_invoices", "summary": "List Sales Invoices", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "required": false, "description": "Search (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "sales_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sales order ID", "title": "Sales Order Id"}, "required": false, "description": "Filter by sales order ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesInvoiceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["accounting.sales-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_sales_invoice", "summary": "Create Sales Invoice", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesInvoiceResponse"}}}}}, "description": "Create a new item.", "tags": ["accounting.sales-invoices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesInvoiceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/sales-invoices/{id}": {"get": {"operationId": "get_sales_invoice", "summary": "Get Sales Invoice", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesInvoiceResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["accounting.sales-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_sales_invoice", "summary": "Update Sales Invoice", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesInvoiceResponse"}}}}}, "description": "Update an item.", "tags": ["accounting.sales-invoices"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/SalesInvoiceUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_sales_invoice", "summary": "Delete Sales Invoice", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["accounting.sales-invoices"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/service-charges": {"get": {"operationId": "list_service_charges", "summary": "List Service Charges", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "required": false, "description": "Search (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "sales_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sales order ID", "title": "Sales Order Id"}, "required": false, "description": "Filter by sales order ID"}, {"in": "query", "name": "billing_statement_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by billing statement ID", "title": "Billing Statement Id"}, "required": false, "description": "Filter by billing statement ID"}, {"in": "query", "name": "source_system", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by source system", "title": "Source System"}, "required": false, "description": "Filter by source system"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceChargeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["accounting.service-charges"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_service_charge", "summary": "Create Service Charge", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceChargeResponse"}}}}}, "description": "Create a new item.", "tags": ["accounting.service-charges"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceChargeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/service-charges/{id}": {"get": {"operationId": "get_service_charge", "summary": "Get Service Charge", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceChargeResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["accounting.service-charges"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_service_charge", "summary": "Update Service Charge", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceChargeResponse"}}}}}, "description": "Update an item.", "tags": ["accounting.service-charges"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceChargeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_service_charge", "summary": "Delete Service Charge", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["accounting.service-charges"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/billing-statements": {"get": {"operationId": "list_billing_statements", "summary": "List Billing Statements", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "required": false, "description": "Search (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "required": false, "description": "Filter by customer ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "required": false, "description": "Filter by status"}, {"in": "query", "name": "billing_period", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billing period", "title": "Billing Period"}, "required": false, "description": "Filter by billing period"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BillingStatementResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["accounting.billing-statements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_billing_statement", "summary": "Create Billing Statement", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingStatementResponse"}}}}}, "description": "Create a new item.", "tags": ["accounting.billing-statements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingStatementCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/billing-statements/{id}": {"get": {"operationId": "get_billing_statement", "summary": "Get Billing Statement", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingStatementResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["accounting.billing-statements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_billing_statement", "summary": "Update Billing Statement", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingStatementResponse"}}}}}, "description": "Update an item.", "tags": ["accounting.billing-statements"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/BillingStatementUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_billing_statement", "summary": "Delete Billing Statement", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["accounting.billing-statements"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/notes": {"get": {"operationId": "list_notes", "summary": "List Notes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "required": false, "description": "Search (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "entity_name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by entity type", "title": "Entity Name"}, "required": false, "description": "Filter by entity type"}, {"in": "query", "name": "entity_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by entity ID", "title": "Entity Id"}, "required": false, "description": "Filter by entity ID"}, {"in": "query", "name": "is_internal", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by internal flag", "title": "Is Internal"}, "required": false, "description": "Filter by internal flag"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/NoteResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["accounting.notes"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_note", "summary": "Create Note", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NoteResponse"}}}}}, "description": "Create a new item.", "tags": ["accounting.notes"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/NoteCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/accounting/v2/notes/{id}": {"get": {"operationId": "get_note", "summary": "Get Note", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NoteResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["accounting.notes"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_note", "summary": "Update Note", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NoteResponse"}}}}}, "description": "Update an item.", "tags": ["accounting.notes"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/NoteUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_note", "summary": "Delete Note", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["accounting.notes"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/files": {"post": {"operationId": "fileupload_api_upload_file", "summary": "Upload File", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileAttachment"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Upload a new file and retrieve it's storage id.", "tags": ["files"], "requestBody": {"content": {"multipart/form-data": {"schema": {"properties": {"file": {"format": "binary", "title": "File", "type": "string"}}, "required": ["file"], "title": "FileParams", "type": "object"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "fileupload_api_list_files", "summary": "List Files", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileList"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get a list of all files in the system.", "tags": ["files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/files/{storage_id}/download": {"get": {"operationId": "fileupload_api_download_file", "summary": "Download File", "parameters": [{"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Download a file.", "tags": ["files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/files/{storage_id}/inline": {"get": {"operationId": "fileupload_api_get_inline_file", "summary": "Get Inline File", "parameters": [{"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Serve a file for inline display, e.g. an image embedded in a comment.", "tags": ["files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/files/{storage_id}": {"get": {"operationId": "fileupload_api_get_file_details", "summary": "Get File Details", "parameters": [{"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/FileList"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get details about specific file(s).\n\nIf storage_id contains comma-separated values, returns details for multiple files.\nOtherwise returns details for a single file wrapped in a list.", "tags": ["files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "fileupload_api_delete_file", "summary": "Delete File", "parameters": [{"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a file.", "tags": ["files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/webhooks/wms/coverage-published": {"post": {"operationId": "projects_api_wms_webhook_handle_wms_coverage_published", "summary": "Handle Wms Coverage Published", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Ack a coverage-published notification and schedule the fan-out off-request.", "tags": ["webhooks.wms"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CoveragePublishedPayload"}}}, "required": true}}}, "/api/webhooks/travel/task-updated": {"post": {"operationId": "projects_api_travel_webhook_handle_travel_task_updated", "summary": "Handle Travel Task Updated", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Resolve the project by code and trigger a project-task recompute.", "tags": ["webhooks.travel"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/TaskUpdatedPayload"}}}, "required": true}}}, "/api/webhooks/pipedrive-sync": {"post": {"operationId": "webhooks_api_pipedrive_sync_webhook", "summary": "Pipedrive Sync Webhook", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Webhook endpoint delegating all processing to the manager.", "tags": ["webhooks"]}}, "/api/webhooks/wrike/dates-changed": {"post": {"operationId": "webhooks_api_handle_wrike_dates_changed_webhook", "summary": "Handle Wrike Dates Changed Webhook", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Acknowledge and ignore Wrike dates-changed events (sync switched off).", "tags": ["webhooks"]}}, "/api/webhooks/wrike/task-created": {"post": {"operationId": "webhooks_api_handle_wrike_task_created_webhook", "summary": "Handle Wrike Task Created Webhook", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Acknowledge and ignore Wrike task-created events (sync switched off).", "tags": ["webhooks"]}}, "/api/webhooks/wrike/custom-field": {"post": {"operationId": "webhooks_api_handle_wrike_custom_field_changed", "summary": "Handle Wrike Custom Field Changed", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Acknowledge and ignore Wrike custom-field events (sync switched off).", "tags": ["webhooks"]}}, "/api/webhooks/wrike/sync-task": {"post": {"operationId": "webhooks_api_handle_wrike_sync_task_webhook", "summary": "Handle Wrike Sync Task Webhook", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Acknowledge and ignore Wrike sync-task events (sync switched off).", "tags": ["webhooks"]}}, "/api/wms/team-requests": {"get": {"operationId": "projects_api_wms_team_requests_list_team_requests", "summary": "List Team Requests", "parameters": [{"in": "query", "name": "project_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "List active TRs visible to WMS, optionally scoped to one project_code.", "tags": ["wms"]}}, "/api/wms/team-requests/{external_id}": {"get": {"operationId": "projects_api_wms_team_requests_get_team_request", "summary": "Get Team Request", "parameters": [{"in": "path", "name": "external_id", "schema": {"title": "External Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Fetch one TR by stable external_id (``opshub-tr-{id}``).\n\n404 when the id is malformed, the TR is soft-deleted, or its status is\noutside the WMS-visible window \u2014 same observable behaviour as the list\nendpoint omitting the row.", "tags": ["wms"]}}, "/api/wms/team-requests/{external_id}/approve": {"post": {"operationId": "projects_api_wms_team_requests_approve_team_request", "summary": "Approve Team Request", "parameters": [{"in": "path", "name": "external_id", "schema": {"title": "External Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Approve every actionable slot of a TR \u2014 WMS-initiated team approval.\n\nMirrors the planner's per-slot approval, but for the whole TR at once.\nThe API key's user must hold ``approve_team_request_slot``; the approval\nis attributed to that user in the activity log.", "tags": ["wms"]}}, "/api/wms/team-requests/{external_id}/slots/{slot_id}/approve": {"post": {"operationId": "projects_api_wms_team_requests_approve_team_request_slot", "summary": "Approve Team Request Slot", "parameters": [{"in": "path", "name": "external_id", "schema": {"title": "External Id", "type": "string"}, "required": true}, {"in": "path", "name": "slot_id", "schema": {"title": "Slot Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Approve a single slot of a TR \u2014 WMS-initiated per-slot confirmation.", "tags": ["wms"]}}, "/api/wms/team-requests/{external_id}/notes": {"get": {"operationId": "projects_api_wms_team_requests_list_team_request_notes", "summary": "List Team Request Notes", "parameters": [{"in": "path", "name": "external_id", "schema": {"title": "External Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Manual notes on a TR's timeline (newest first).", "tags": ["wms"]}, "post": {"operationId": "projects_api_wms_team_requests_create_team_request_note", "summary": "Create Team Request Note", "parameters": [{"in": "path", "name": "external_id", "schema": {"title": "External Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}, "404": {"description": "Not Found", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "Append a manual note to a TR (WMS-initiated).", "tags": ["wms"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/_NotePayload"}}}, "required": true}}}, "/api/wms/vehicle-assignments": {"get": {"operationId": "projects_api_wms_vehicle_assignments_list_vehicle_assignments", "summary": "List Vehicle Assignments", "parameters": [{"in": "query", "name": "project_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"title": "Response", "type": "object"}}}}}, "description": "List ACCEPTED vehicle assignments, optionally scoped to one project_code.", "tags": ["wms"]}}, "/api/netsuite/projects/{netsuite_project_id}": {"delete": {"operationId": "integrations_netsuite_api_delete_project", "summary": "Delete Project", "parameters": [{"in": "path", "name": "netsuite_project_id", "schema": {"title": "Netsuite Project Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a NetSuite project.", "tags": ["netsuite"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/netsuite/assets/{asset_id}": {"delete": {"operationId": "integrations_netsuite_api_delete_asset", "summary": "Delete Asset", "parameters": [{"in": "path", "name": "asset_id", "schema": {"title": "Asset Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a NetSuite asset.", "tags": ["netsuite"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/netsuite/customers/{customer_id}": {"delete": {"operationId": "integrations_netsuite_api_delete_customer", "summary": "Delete Customer", "parameters": [{"in": "path", "name": "customer_id", "schema": {"title": "Customer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Delete a NetSuite customer.", "tags": ["netsuite"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/netsuite/sales-orders/by-project-code": {"get": {"operationId": "integrations_netsuite_api_get_all_sales_order_by_project_code", "summary": "Get All Sales Order By Project Code", "parameters": [{"in": "query", "name": "project_code", "schema": {"title": "Project Code", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/SalesOrder"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get all sales order by project code.", "tags": ["netsuite"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/netsuite/subsidiaries": {"get": {"operationId": "integrations_netsuite_api_get_subsidiaries", "summary": "Get Subsidiaries", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Subsidiary"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get all Aerones billing entities from NetSuite, each annotated with the\ncustomer countries it is the billing default for.", "tags": ["netsuite"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/netsuite/refresh-master-data": {"post": {"operationId": "integrations_netsuite_api_refresh_master_data", "summary": "Refresh Master Data", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Refresh master data from NetSuite.\n\nThis syncs:\n- Units of measure to ServicePricingUnit\n- Service items with their unit relations", "tags": ["netsuite"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/scheduler": {"get": {"operationId": "builderapi_scheduler_api_get_scheduler_jobs", "summary": "Get Scheduler Jobs", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SchedulerJobList"}}}}}, "description": "Return list of scheduler jobs.", "tags": ["utilities"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/email": {"post": {"operationId": "emailtemplater_api_send_email", "summary": "Send Email", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendEmailResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Send an email using the asynchronous email service.\n\nResponse indicates that email is queued for sending. It does not necessarily\nmean that it has already been sent out to each recipient. However, if email\ncould not be queued, for reasons like invalid request or some other errors,\nthis would be indicated in the response.\n\nOn success also returns `tracking_id`, for `GET .../status`.", "tags": ["email"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EmailRequest"}}}, "required": true}, "security": [{"AuthBearer": []}]}}, "/api/email-preview": {"post": {"operationId": "emailtemplater_api_send_email_preview", "summary": "Send Email Preview", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get an email preview that would be sent to user.", "tags": ["email"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/EmailContext"}}}, "required": true}, "security": [{"AuthBearer": []}]}}, "/api/email/{tracking_id}/status": {"get": {"operationId": "emailtemplater_api_get_sent_email_status", "summary": "Get Sent Email Status", "parameters": [{"in": "path", "name": "tracking_id", "schema": {"format": "uuid", "title": "Tracking Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SentEmailStatusResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Look up the current status of a send by its `tracking_id`.", "tags": ["email"], "security": [{"AuthBearer": []}]}}, "/api/email/{tracking_id}/pixel.gif": {"get": {"operationId": "emailtemplater_api_track_sent_email_opened", "summary": "Track Sent Email Opened", "parameters": [{"in": "path", "name": "tracking_id", "schema": {"title": "Tracking Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Return a 1x1 GIF and record the first open. Unauthenticated by design.", "tags": ["email"]}}, "/api/deviations/filters": {"get": {"operationId": "deviations_api_get_global_deviations_filters", "summary": "Get Global Deviations Filters", "parameters": [{"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "required": false, "description": "Filter by start date (YYYY-MM-DD)"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "required": false, "description": "Filter by end date (YYYY-MM-DD)"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GlobalDeviationsFilters"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get available filter values for global deviations.\n\nArgs:\n request: HTTP request object\n params: Query parameters with optional start_date and end_date\n\nReturns:\n GlobalDeviationsFilters with projectCodes, countryCodes, and regions", "tags": ["deviations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/deviations/summary": {"get": {"operationId": "deviations_api_get_global_deviations_summary", "summary": "Get Global Deviations Summary", "parameters": [{"in": "query", "name": "period_type", "schema": {"allOf": [{"description": "Global period type enumeration (weekly or monthly).", "enum": ["weekly", "monthly"], "title": "GlobalPeriodTypeEnum", "type": "string"}], "default": "weekly", "description": "Period type: 'weekly' (default) or 'monthly'"}, "required": false, "description": "Period type: 'weekly' (default) or 'monthly'"}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "required": false, "description": "Filter by start date (YYYY-MM-DD)"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "required": false, "description": "Filter by end date (YYYY-MM-DD)"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Partial match search on project code (case-insensitive)", "title": "Search"}, "required": false, "description": "Partial match search on project code (case-insensitive)"}, {"in": "query", "name": "project_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by exact project codes (comma-separated)", "title": "Project Codes"}, "required": false, "description": "Filter by exact project codes (comma-separated)"}, {"in": "query", "name": "country_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by country codes (comma-separated alpha-2)", "title": "Country Code"}, "required": false, "description": "Filter by country codes (comma-separated alpha-2)"}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "required": false, "description": "Filter by regions (comma-separated)"}, {"in": "query", "name": "filter_currency", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency for financial filters (EUR, USD, or AUD)", "title": "Filter Currency"}, "required": false, "description": "Currency for financial filters (EUR, USD, or AUD)"}, {"in": "query", "name": "fixed_planned_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned value", "title": "Fixed Planned Min"}, "required": false, "description": "Minimum fixed planned value"}, {"in": "query", "name": "fixed_planned_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned value", "title": "Fixed Planned Max"}, "required": false, "description": "Maximum fixed planned value"}, {"in": "query", "name": "actual_planned_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned value", "title": "Actual Planned Min"}, "required": false, "description": "Minimum actual planned value"}, {"in": "query", "name": "actual_planned_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned value", "title": "Actual Planned Max"}, "required": false, "description": "Maximum actual planned value"}, {"in": "query", "name": "amount_charged_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum amount charged", "title": "Amount Charged Min"}, "required": false, "description": "Minimum amount charged"}, {"in": "query", "name": "amount_charged_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum amount charged", "title": "Amount Charged Max"}, "required": false, "description": "Maximum amount charged"}, {"in": "query", "name": "deviation_from_actual_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from actual", "title": "Deviation From Actual Min"}, "required": false, "description": "Minimum deviation from actual"}, {"in": "query", "name": "deviation_from_actual_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from actual", "title": "Deviation From Actual Max"}, "required": false, "description": "Maximum deviation from actual"}, {"in": "query", "name": "deviation_from_fixed_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from fixed", "title": "Deviation From Fixed Min"}, "required": false, "description": "Minimum deviation from fixed"}, {"in": "query", "name": "deviation_from_fixed_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from fixed", "title": "Deviation From Fixed Max"}, "required": false, "description": "Maximum deviation from fixed"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GlobalDeviationsSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get aggregated summary of global deviations with the same filtering as GET /deviations.\n\nArgs:\n request: HTTP request object\n params: Query parameters for filtering (same as deviations endpoint except pagination)\n\nReturns:\n GlobalDeviationsSummary with aggregated financial totals", "tags": ["deviations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/deviations/{project_id}/filters": {"get": {"operationId": "deviations_api_get_project_deviations_filters", "summary": "Get Project Deviations Filters", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "required": false, "description": "Filter by start date (YYYY-MM-DD)"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "required": false, "description": "Filter by end date (YYYY-MM-DD)"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectDeviationsFilters"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get available filter values for a project's deviations.\n\nArgs:\n request: HTTP request object\n project_id: Project UUID\n params: Query parameters with optional start_date and end_date\n\nReturns:\n ProjectDeviationsFilters with roboticSets and serviceCodes", "tags": ["deviations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/deviations/{project_id}/summary": {"get": {"operationId": "deviations_api_get_project_deviations_summary", "summary": "Get Project Deviations Summary", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "period_type", "schema": {"allOf": [{"description": "Period type enumeration.", "enum": ["daily", "weekly"], "title": "PeriodTypeEnum", "type": "string"}], "default": "daily", "description": "Period type: 'daily' (default) or 'weekly'"}, "required": false, "description": "Period type: 'daily' (default) or 'weekly'"}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "required": false, "description": "Filter by start date (YYYY-MM-DD)"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "required": false, "description": "Filter by end date (YYYY-MM-DD)"}, {"in": "query", "name": "robotic_set", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robotic set", "title": "Robotic Set"}, "required": false, "description": "Filter by robotic set"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}, "required": false, "description": "Filter by service code"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ProjectDeviationsSummary"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get aggregated summary of a project's deviations.\n\nArgs:\n request: HTTP request object\n project_id: Project UUID\n params: Query parameters for filtering\n\nReturns:\n ProjectDeviationsSummary with aggregated financial totals", "tags": ["deviations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/deviations/{project_id}": {"get": {"operationId": "deviations_api_get_project_deviations", "summary": "Get Project Deviations", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}, {"in": "query", "name": "period_type", "schema": {"allOf": [{"description": "Period type enumeration.", "enum": ["daily", "weekly"], "title": "PeriodTypeEnum", "type": "string"}], "default": "daily", "description": "Period type: 'daily' (default) or 'weekly'"}, "required": false, "description": "Period type: 'daily' (default) or 'weekly'"}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "required": false, "description": "Filter by start date (YYYY-MM-DD)"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "required": false, "description": "Filter by end date (YYYY-MM-DD)"}, {"in": "query", "name": "robotic_set", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robotic set", "title": "Robotic Set"}, "required": false, "description": "Filter by robotic set"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}, "required": false, "description": "Filter by service code"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number for pagination", "title": "Page", "type": "integer"}, "required": false, "description": "Page number for pagination"}, {"in": "query", "name": "page_size", "schema": {"default": 10, "description": "Number of items per page", "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}, {"in": "query", "name": "format", "schema": {"anyOf": [{"$ref": "#/components/schemas/ExportFormat"}, {"type": "null"}], "description": "Export format: 'csv' or 'xlsx'. If not provided, returns JSON."}, "required": false, "description": "Export format: 'csv' or 'xlsx'. If not provided, returns JSON."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeviationsListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get deviation data for a project.\n\nArgs:\n request: HTTP request object\n project_id: Project UUID\n params: Query parameters for filtering, pagination, and export format\n\nReturns:\n DeviationsListResponse with deviation data, or file response if format specified", "tags": ["deviations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "deviations_api_update_project_deviations", "summary": "Update Project Deviations", "parameters": [{"in": "path", "name": "project_id", "schema": {"format": "uuid", "title": "Project Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeviationsPatchResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update deviation rows for a project (bulk update).\n\nArgs:\n request: HTTP request object\n project_id: Project UUID\n payload: List of deviation update items\n\nReturns:\n DeviationsPatchResponse with update results", "tags": ["deviations"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DeviationUpdateItem"}, "title": "Payload", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/deviations": {"get": {"operationId": "deviations_api_get_global_deviations", "summary": "Get Global Deviations", "parameters": [{"in": "query", "name": "period_type", "schema": {"allOf": [{"description": "Global period type enumeration (weekly or monthly).", "enum": ["weekly", "monthly"], "title": "GlobalPeriodTypeEnum", "type": "string"}], "default": "weekly", "description": "Period type: 'weekly' (default) or 'monthly'"}, "required": false, "description": "Period type: 'weekly' (default) or 'monthly'"}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "required": false, "description": "Filter by start date (YYYY-MM-DD)"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "required": false, "description": "Filter by end date (YYYY-MM-DD)"}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Partial match search on project code (case-insensitive)", "title": "Search"}, "required": false, "description": "Partial match search on project code (case-insensitive)"}, {"in": "query", "name": "project_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by exact project codes (comma-separated, e.g. 'EBUS-4885,GEFI-4916')", "title": "Project Codes"}, "required": false, "description": "Filter by exact project codes (comma-separated, e.g. 'EBUS-4885,GEFI-4916')"}, {"in": "query", "name": "country_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by country codes (comma-separated alpha-2, e.g. 'BE,DE,FR')", "title": "Country Code"}, "required": false, "description": "Filter by country codes (comma-separated alpha-2, e.g. 'BE,DE,FR')"}, {"in": "query", "name": "region", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated, e.g. 'Europe,North America')", "title": "Region"}, "required": false, "description": "Filter by regions (comma-separated, e.g. 'Europe,North America')"}, {"in": "query", "name": "filter_currency", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency for financial filters (EUR, USD, or AUD)", "title": "Filter Currency"}, "required": false, "description": "Currency for financial filters (EUR, USD, or AUD)"}, {"in": "query", "name": "fixed_planned_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned value", "title": "Fixed Planned Min"}, "required": false, "description": "Minimum fixed planned value"}, {"in": "query", "name": "fixed_planned_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned value", "title": "Fixed Planned Max"}, "required": false, "description": "Maximum fixed planned value"}, {"in": "query", "name": "actual_planned_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned value", "title": "Actual Planned Min"}, "required": false, "description": "Minimum actual planned value"}, {"in": "query", "name": "actual_planned_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned value", "title": "Actual Planned Max"}, "required": false, "description": "Maximum actual planned value"}, {"in": "query", "name": "amount_charged_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum amount charged", "title": "Amount Charged Min"}, "required": false, "description": "Minimum amount charged"}, {"in": "query", "name": "amount_charged_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum amount charged", "title": "Amount Charged Max"}, "required": false, "description": "Maximum amount charged"}, {"in": "query", "name": "deviation_from_actual_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from actual", "title": "Deviation From Actual Min"}, "required": false, "description": "Minimum deviation from actual"}, {"in": "query", "name": "deviation_from_actual_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from actual", "title": "Deviation From Actual Max"}, "required": false, "description": "Maximum deviation from actual"}, {"in": "query", "name": "deviation_from_fixed_min", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from fixed", "title": "Deviation From Fixed Min"}, "required": false, "description": "Minimum deviation from fixed"}, {"in": "query", "name": "deviation_from_fixed_max", "schema": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from fixed", "title": "Deviation From Fixed Max"}, "required": false, "description": "Maximum deviation from fixed"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number for pagination", "title": "Page", "type": "integer"}, "required": false, "description": "Page number for pagination"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}, {"in": "query", "name": "format", "schema": {"anyOf": [{"$ref": "#/components/schemas/ExportFormat"}, {"type": "null"}], "description": "Export format: 'csv' or 'xlsx'. If not provided, returns JSON."}, "required": false, "description": "Export format: 'csv' or 'xlsx'. If not provided, returns JSON."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GlobalDeviationsListResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get global deviation data aggregated across all projects.\n\nArgs:\n request: HTTP request object\n params: Query parameters for filtering, pagination, and export format\n\nReturns:\n GlobalDeviationsListResponse with aggregated deviation data, or file if format specified", "tags": ["deviations"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "deviations_api_update_global_deviations", "summary": "Update Global Deviations", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeviationsPatchResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update global deviation comments (bulk update).\n\nArgs:\n request: HTTP request object\n payload: List of global deviation update items\n\nReturns:\n DeviationsPatchResponse with update results", "tags": ["deviations"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/GlobalDeviationUpdateItem"}, "title": "Payload", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/common/unified-services": {"get": {"operationId": "core_endpoints_services_get_unified_services", "summary": "Get unified services as HTML table", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UnifiedServices"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get all unified services with their full names and codes in an HTML table format. Requires a valid public access token as a parameter ?token=", "tags": ["confluence"]}}, "/api/services/line-items": {"get": {"operationId": "core_endpoints_services_get_service_line_items", "summary": "Get Service Line Items", "parameters": [{"in": "query", "name": "category", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service category name.", "title": "Category"}, "required": false, "description": "Filter by service category name."}, {"in": "query", "name": "group", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service group name.", "title": "Group"}, "required": false, "description": "Filter by service group name."}, {"in": "query", "name": "service", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item is reported as service.", "title": "Service"}, "required": false, "description": "Filter by whether item is reported as service."}, {"in": "query", "name": "rat", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item is provided by RAT.", "title": "Rat"}, "required": false, "description": "Filter by whether item is provided by RAT."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceLineItem"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return all service line items in unified format.", "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/services/line-items/{code}": {"get": {"operationId": "core_endpoints_services_get_service_line_item", "summary": "Get Service Line Item", "parameters": [{"in": "path", "name": "code", "schema": {"title": "Code", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ServiceLineItemFull"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return a single service line item by code.", "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/turbine-manufacturers": {"get": {"operationId": "turbines_api_get_turbine_manufacturers", "summary": "Get Turbine Manufacturers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TurbineManufacturerResponse"}}}}}, "description": "Get all turbine manufacturers.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/turbine-models": {"get": {"operationId": "turbines_api_get_all_turbine_models", "summary": "Get All Turbine Models", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LegacyTurbineModelResponse"}}}}}, "description": "Get all turbine models.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/turbine-models/{manufacturer_id}": {"get": {"operationId": "turbines_api_get_turbine_models", "summary": "Get Turbine Models", "parameters": [{"in": "path", "name": "manufacturer_id", "schema": {"title": "Manufacturer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LegacyTurbineModelResponse"}}}}}, "description": "Get turbine models for a specific manufacturer.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/refresh-cache": {"post": {"operationId": "turbines_api_refresh_turbine_data", "summary": "Refresh Turbine Data", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RefreshResponse"}}}}}, "description": "Refresh turbine data from the API.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/blade-manufacturers": {"get": {"operationId": "turbines_api_get_blade_manufacturers", "summary": "Get Blade Manufacturers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BladeManufacturerResponse"}}}}}, "description": "Get all blade manufacturers.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/blade-models": {"get": {"operationId": "turbines_api_get_all_blade_models", "summary": "Get All Blade Models", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LegacyBladeModelResponse"}}}}}, "description": "Get all blade models.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/turbines/blade-models/{manufacturer_id}": {"get": {"operationId": "turbines_api_get_blade_models", "summary": "Get Blade Models", "parameters": [{"in": "path", "name": "manufacturer_id", "schema": {"title": "Manufacturer Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LegacyBladeModelResponse"}}}}}, "description": "Get blade models for a specific manufacturer.", "tags": ["turbines"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/countries": {"get": {"operationId": "countries_api_get_supported_countries", "summary": "Get Supported Countries", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Country"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return list of supported countries with their alpha-2 codes.\n\nDEPRECATED: This endpoint is deprecated. Use /core/v1/countries instead.\n\nReturns only enabled countries from the core.Country table.", "tags": ["misc"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/users": {"get": {"operationId": "permissions_api_get_users", "summary": "Get Users", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/User"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return list of all users with their roles.\n\nDEPRECATED: Use /core/v1/users instead.", "tags": ["users"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/users/{user_id}": {"patch": {"operationId": "permissions_api_update_user_role", "summary": "Update User Role", "parameters": [{"in": "path", "name": "user_id", "schema": {"title": "User Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/User"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Update user role.\n\nOnly admin can change roles.\nCan set/unset admin and project manager roles.", "tags": ["users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateUserRole"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/customers": {"get": {"operationId": "customers_api_get_customers", "summary": "Get Customers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Customer"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return local customers linked to NetSuite.\n\nDEPRECATED: Use /core/v1/customers instead.", "tags": ["misc"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "customers_api_create_customer", "summary": "Create Customer", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "REMOVED: use POST /core/v1/customers instead.\n\nIt created a NetSuite customer with no local row \u2014 a guaranteed unlinked\nduplicate. 410-gated; the read endpoints above remain.", "tags": ["misc"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/customers/subsidiaries/": {"get": {"operationId": "customers_api_get_subsidiaries", "summary": "Get Subsidiaries", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/Subsidiary"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get subsidiaries from NetSuite.\n\nDEPRECATED: Use /core/v1/customers instead.", "tags": ["misc"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/integrations/vestas-cir/v1/{service_order_line_id}/validate": {"get": {"operationId": "core_endpoints_vestas_cir_validate_vestas_cir", "summary": "Validate SOL data before CIR submission.", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CIRValidationResultSchema"}}}}}, "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/integrations/vestas-cir/v1/{service_order_line_id}/status": {"get": {"operationId": "core_endpoints_vestas_cir_get_cir_submission_status", "summary": "Get latest CIR submission status for a SOL.", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CIRSubmissionStatusSchema"}}}}}, "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/integrations/vestas-cir/v1/{service_order_line_id}": {"post": {"operationId": "core_endpoints_vestas_cir_submit_vestas_cir", "summary": "Submit service order line to Vestas CIR.", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CIRSubmitResponseSchema"}}}}}, "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/integrations/vestas-cir/v1/{service_order_line_id}/data": {"get": {"operationId": "core_endpoints_vestas_cir_get_sol_data", "summary": "Fetch all files associated with a given service order line ID.", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VestasCIRDataSchema"}}}}}, "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/integrations/nordex-cir/v1/reports/{incident_number}/data": {"get": {"operationId": "core_endpoints_nordex_cir_get_nordex_cir_report_data", "summary": "Fetch the raw inspection data behind one Nordex report.", "parameters": [{"in": "path", "name": "incident_number", "schema": {"title": "Incident Number", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/NordexCIRDataSchema"}}}}}, "description": "404 when no active, non-cancelled Nordex service order line carries the\nincident number. 422 when a line belongs to a non-Nordex customer, is not an\nIIN service, or the lines span more than one customer or turbine.", "tags": ["misc"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/data-tracking/status-counts": {"get": {"operationId": "get_data_tracking_status_counts", "summary": "Per-stage data tracking status counts for a batch of lines", "parameters": [{"in": "query", "name": "service_order_line_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated service order line ids, max 100 per request.", "title": "Service Order Line Ids"}, "required": false, "description": "Comma-separated service order line ids, max 100 per request."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DataTrackingStatusCountsResponse"}}}}}, "description": "Count tracked files per stage and status, without paging the file list.", "tags": ["data-tracking"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/data-tracking/service-order-lines/{service_order_line_id}": {"post": {"operationId": "create_data_tracking_for_service_order_line", "summary": "Create or extend the system workorder for service order line files", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataTrackingResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Create a DATA_TRACKING workorder with one metadata row per file per stage.", "tags": ["data-tracking"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataTrackingCreateRequest"}, "title": "Payload", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_data_tracking_for_service_order_line", "summary": "Update data tracking statuses for service order line files", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataTrackingResponse"}, "title": "Response", "type": "array"}}}}}, "description": "Update status or error fields stored on data tracking stage rows.", "tags": ["data-tracking"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataTrackingUpdateRequest"}, "title": "Payload", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "list_data_tracking_for_service_order_line", "summary": "List data tracking records for a service order line", "parameters": [{"in": "path", "name": "service_order_line_id", "schema": {"title": "Service Order Line Id", "type": "integer"}, "required": true}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataTrackingResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all tracked files for a service order line (one item per file).", "tags": ["data-tracking"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/data-tracking/files": {"get": {"operationId": "list_data_tracking_files", "summary": "List data tracking records across several service order lines", "parameters": [{"in": "query", "name": "service_order_line_ids", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated service order line ids, max 100 per request.", "title": "Service Order Line Ids"}, "required": false, "description": "Comma-separated service order line ids, max 100 per request."}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 500, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DataTrackingBatchResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List tracked files across several service order lines (one item per file).\n\nThe batched form of ``GET /service-order-lines/{id}``: same item shape plus\n``service_order_line_id``, same pagination headers, so a caller's existing\npaging loop carries over. Pagination is not disableable here \u2014 a batch can\nspan tens of thousands of files.", "tags": ["data-tracking"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/services": {"get": {"operationId": "services_api_get_services", "summary": "Get Services", "parameters": [{"in": "query", "name": "category", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service category.", "title": "Category"}, "required": false, "description": "Service category."}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type (WTG, BLADE).", "title": "Type"}, "required": false, "description": "Asset type (WTG, BLADE)."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServiceList"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve service list.\n\nDEPRECATED: Use /core/v1/services instead.", "tags": ["services"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/services/pre-job/questions/{service_code}": {"get": {"operationId": "services_api_get_pre_job_questions", "summary": "Get Pre Job Questions", "parameters": [{"in": "path", "name": "service_code", "schema": {"title": "Service Code", "type": "string"}, "required": true}, {"in": "query", "name": "addons", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional service codes that can/or are added to the service.", "title": "Addons"}, "required": false, "description": "Additional service codes that can/or are added to the service."}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ServicePreJobQuestionDefinition"}, "title": "Response", "type": "array"}}}}}, "description": "Retrieve pre-job questions for a specific service code and optional addons.", "tags": ["services"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/services/{service_code}": {"get": {"operationId": "services_api_get_service", "summary": "Get Service", "parameters": [{"in": "path", "name": "service_code", "schema": {"title": "Service Code", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Service"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Retrieve service.\n\nDEPRECATED: Use /core/v1/services instead.", "tags": ["services"], "deprecated": true, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/bamboohr/v1/employees": {"get": {"operationId": "list_bamboohr_employees", "summary": "List BambooHR Employees", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by display name, first/last name, or work email (case-insensitive).", "title": "Search"}, "required": false, "description": "Search by display name, first/last name, or work email (case-insensitive)."}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by employment status (ACTIVE, INACTIVE, TERMINATED)", "title": "Status"}, "required": false, "description": "Filter by employment status (ACTIVE, INACTIVE, TERMINATED)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/BambooHREmployeeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["bamboohr.employees"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/maintainx/v1/assets": {"get": {"operationId": "list_maintainx_assets", "summary": "List MaintainX Assets", "parameters": [{"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "external_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by MaintainX asset ID", "title": "External Id"}, "required": false, "description": "Filter by MaintainX asset ID"}, {"in": "query", "name": "external_organization_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by MaintainX organization ID", "title": "External Organization Id"}, "required": false, "description": "Filter by MaintainX organization ID"}, {"in": "query", "name": "robot_set_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by linked core RobotSet ID", "title": "Robot Set Id"}, "required": false, "description": "Filter by linked core RobotSet ID"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AssetResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["maintainx.assets"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/talentlms/v1/users": {"get": {"operationId": "list_talentlms_users", "summary": "List TalentLMS Users", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by full name, first/last name, or email (case-insensitive).", "title": "Search"}, "required": false, "description": "Search by full name, first/last name, or email (case-insensitive)."}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "required": false, "description": "Sort by field (prefix with - for descending)"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by user status (ACTIVE, INACTIVE)", "title": "Status"}, "required": false, "description": "Filter by user status (ACTIVE, INACTIVE)"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TalentLMSUserResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and filtering.", "tags": ["talentlms.users"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/v1/payroll/activities": {"post": {"operationId": "payroll_api_activities_create_activity", "summary": "Create Activity", "parameters": [], "responses": {"201": {"description": "Created", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PayrollActivityOut"}}}}}, "tags": ["payroll"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PayrollActivityIn"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "get": {"operationId": "payroll_api_activities_list_activities", "summary": "List Activities", "parameters": [{"in": "query", "name": "resource_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "required": false}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Start Date"}, "required": false}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "End Date"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PayrollActivityOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["payroll"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/v1/payroll/activities/{id}": {"get": {"operationId": "payroll_api_activities_get_activity", "summary": "Get Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PayrollActivityOut"}}}}}, "tags": ["payroll"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "payroll_api_activities_update_activity", "summary": "Update Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PayrollActivityOut"}}}}}, "tags": ["payroll"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PayrollActivityPatchIn"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "payroll_api_activities_delete_activity", "summary": "Delete Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"204": {"description": "No Content"}}, "tags": ["payroll"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/v1/payroll/timesheets": {"get": {"operationId": "list_timesheets", "summary": "List timesheets", "parameters": [{"in": "query", "name": "resource_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource", "title": "Resource Id"}, "required": false, "description": "Filter by resource"}, {"in": "query", "name": "start_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter from date", "title": "Start Date"}, "required": false, "description": "Filter from date"}, {"in": "query", "name": "end_date", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter until date", "title": "End Date"}, "required": false, "description": "Filter until date"}, {"in": "query", "name": "project_id", "schema": {"description": "Filter by project IDs", "items": {"type": "integer"}, "title": "Project Id", "type": "array"}, "required": false, "description": "Filter by project IDs"}, {"in": "query", "name": "robot_set_id", "schema": {"description": "Filter by robot set IDs", "items": {"type": "integer"}, "title": "Robot Set Id", "type": "array"}, "required": false, "description": "Filter by robot set IDs"}, {"in": "query", "name": "work_time_category_id", "schema": {"description": "Filter by work time category IDs", "items": {"type": "integer"}, "title": "Work Time Category Id", "type": "array"}, "required": false, "description": "Filter by work time category IDs"}, {"in": "query", "name": "exclude_null_work_time_category", "schema": {"default": false, "description": "Exclude entries where work time category is not assigned", "title": "Exclude Null Work Time Category", "type": "boolean"}, "required": false, "description": "Exclude entries where work time category is not assigned"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TimesheetEntryOut"}, "title": "Response", "type": "array"}}}}}, "tags": ["payroll"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/active-workload/service-order-lines": {"get": {"operationId": "active_workload_api_list_service_order_lines", "summary": "List Service Order Lines", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by service code, description, or SO number", "title": "Search"}, "required": false, "description": "Search by service code, description, or SO number"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix with '-' for descending. Allowed: service_code, status, number", "title": "Sort"}, "required": false, "description": "Sort field, prefix with '-' for descending. Allowed: service_code, status, number"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "required": false, "description": "Filter by customer ID"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "required": false, "description": "Filter by country ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by SOL status", "title": "Status"}, "required": false, "description": "Filter by SOL status"}, {"in": "query", "name": "service_codes", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated service codes to filter by", "title": "Service Codes"}, "required": false, "description": "Comma-separated service codes to filter by"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SO date on or after", "title": "Date From"}, "required": false, "description": "Filter SO date on or after"}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SO date on or before", "title": "Date To"}, "required": false, "description": "Filter SO date on or before"}, {"in": "query", "name": "project_manager_user_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project manager user ID", "title": "Project Manager User Id"}, "required": false, "description": "Filter by project manager user ID"}, {"in": "query", "name": "include_cancelled", "schema": {"default": false, "description": "Include cancelled lines", "title": "Include Cancelled", "type": "boolean"}, "required": false, "description": "Include cancelled lines"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ActiveWorkloadSOLResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List service order lines for active workload view.", "tags": ["active-workload"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/active-workload/service-order-lines/{sol_id}": {"get": {"operationId": "active_workload_api_get_service_order_line_detail", "summary": "Get Service Order Line Detail", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ActiveWorkloadSOLDetailResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get service order line detail with nested workorders.", "tags": ["active-workload"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/active-workload/work-orders": {"get": {"operationId": "active_workload_api_list_work_orders", "summary": "List Work Orders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by workorder name (case-insensitive)", "title": "Search"}, "required": false, "description": "Search by workorder name (case-insensitive)"}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix with '-' for descending. Allowed: name, status, planned_start_date, planned_end_date, so_number, latest_activity", "title": "Sort"}, "required": false, "description": "Sort field, prefix with '-' for descending. Allowed: name, status, planned_start_date, planned_end_date, so_number, latest_activity"}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "required": false, "description": "Filter by project ID"}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "required": false, "description": "Filter by customer ID"}, {"in": "query", "name": "location_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "required": false, "description": "Filter by location ID"}, {"in": "query", "name": "country_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "required": false, "description": "Filter by country ID"}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status (comma-separated for multiple)", "title": "Status"}, "required": false, "description": "Filter by status (comma-separated for multiple)"}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "required": false, "description": "Filter by turbine ID"}, {"in": "query", "name": "component_type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component type ID", "title": "Component Type Id"}, "required": false, "description": "Filter by component type ID"}, {"in": "query", "name": "type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by WO type (FIELD, ADMIN, OFFICE, DATA_UPLOAD)", "title": "Type"}, "required": false, "description": "Filter by WO type (FIELD, ADMIN, OFFICE, DATA_UPLOAD)"}, {"in": "query", "name": "resource_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource ID", "title": "Resource Id"}, "required": false, "description": "Filter by resource ID"}, {"in": "query", "name": "resource_set_name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by resource set name", "title": "Resource Set Name"}, "required": false, "description": "Filter by resource set name"}, {"in": "query", "name": "service_code", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated service codes to filter by (matches service_order_line.service_code)", "title": "Service Code"}, "required": false, "description": "Comma-separated service codes to filter by (matches service_order_line.service_code)"}, {"in": "query", "name": "date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned start on or after", "title": "Date From"}, "required": false, "description": "Filter planned start on or after"}, {"in": "query", "name": "date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned end on or before", "title": "Date To"}, "required": false, "description": "Filter planned end on or before"}, {"in": "query", "name": "activity_date_from", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter WOs with activities whose time report overlaps this start date", "title": "Activity Date From"}, "required": false, "description": "Filter WOs with activities whose time report overlaps this start date"}, {"in": "query", "name": "activity_date_to", "schema": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter WOs with activities whose time report overlaps this end date", "title": "Activity Date To"}, "required": false, "description": "Filter WOs with activities whose time report overlaps this end date"}, {"in": "query", "name": "project_manager_user_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project manager user ID", "title": "Project Manager User Id"}, "required": false, "description": "Filter by project manager user ID"}, {"in": "query", "name": "include_cancelled", "schema": {"default": false, "description": "Include cancelled work orders", "title": "Include Cancelled", "type": "boolean"}, "required": false, "description": "Include cancelled work orders"}, {"in": "query", "name": "has_inspection", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter WOs with (true) or without (false) inspection data", "title": "Has Inspection"}, "required": false, "description": "Filter WOs with (true) or without (false) inspection data"}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ActiveWorkloadWOResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List work orders for active workload view.", "tags": ["active-workload"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/active-workload/work-orders/{wo_id}": {"get": {"operationId": "active_workload_api_get_work_order_detail", "summary": "Get Work Order Detail", "parameters": [{"in": "path", "name": "wo_id", "schema": {"title": "Wo Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ActiveWorkloadWODetailResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Get work order detail with activities and resource sets.", "tags": ["active-workload"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/active-workload/filters": {"get": {"operationId": "active_workload_api_get_filters", "summary": "Get Filters", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ActiveWorkloadFiltersResponse"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "Return distinct filter options for active workload views.", "tags": ["active-workload"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/inspections/{sol_id}/": {"get": {"operationId": "vis_api_get_inspection", "summary": "Fetch inspection data for a given service order line ID.", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}, {"in": "query", "name": "component_name", "schema": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Filter by component name (exact match).", "title": "Component Name"}, "required": false, "description": "Filter by component name (exact match)."}, {"in": "query", "name": "component_id", "schema": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Filter by turbine component id (exact match).", "title": "Component Id"}, "required": false, "description": "Filter by turbine component id (exact match)."}, {"in": "query", "name": "section_name", "schema": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Filter sections by name (exact match).", "title": "Section Name"}, "required": false, "description": "Filter sections by name (exact match)."}, {"in": "query", "name": "return_sections", "schema": {"default": true, "description": "Include component sections in the response.", "title": "Return Sections", "type": "boolean"}, "required": false, "description": "Include component sections in the response."}, {"in": "query", "name": "return_data", "schema": {"default": true, "description": "Include all media data.", "title": "Return Data", "type": "boolean"}, "required": false, "description": "Include all media data."}, {"in": "query", "name": "return_urls", "schema": {"default": true, "description": "Include signed URLs for media data.", "title": "Return Urls", "type": "boolean"}, "required": false, "description": "Include signed URLs for media data."}, {"in": "query", "name": "root_photo_ordering", "schema": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "distance,name,file_name,angle"}}, "title": "Root Photo Ordering", "type": "string"}, "required": false, "examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "distance,name,file_name,angle"}}}, {"in": "query", "name": "poi_photo_ordering", "schema": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "distance,name,file_name,angle"}}, "title": "Poi Photo Ordering", "type": "string"}, "required": false, "examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "distance,name,file_name,angle"}}}, {"in": "query", "name": "external_photo_ordering", "schema": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "name,file_name"}}, "title": "External Photo Ordering", "type": "string"}, "required": false, "examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "name,file_name"}}}, {"in": "query", "name": "ler_photo_ordering", "schema": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "name,file_name"}}, "title": "Ler Photo Ordering", "type": "string"}, "required": false, "examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "name,file_name"}}}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/InspectionSchema"}}}}}, "description": "Fetch inspection data for a given service order line ID.", "tags": ["vis.inspections"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/inspections/{sol_id}/components/": {"get": {"operationId": "vis_api_get_inspection_components", "summary": "Fetch components for a given inspection service order line ID.", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ComponentSchema"}, "title": "Response", "type": "array"}}}}}, "description": "Fetch components for a given inspection service order line ID.", "tags": ["vis.inspections"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/inspections/{sol_id}/components/links/": {"post": {"operationId": "vis_api_post_inspection_component_links", "summary": "Create component links for a given inspection service order line ID.", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ComponentSchema"}, "title": "Response", "type": "array"}}}}}, "description": "Create component links for a given inspection service order line ID.", "tags": ["vis.inspections"], "requestBody": {"content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PostComponentLinkSchema"}, "title": "Body", "type": "array"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "vis_api_delete_inspection_component_links", "summary": "Delete component links for a given inspection service order line ID.", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Delete component links for a given inspection service order line ID.", "tags": ["vis.inspections"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/inspections/{sol_id}/authorize-media": {"post": {"operationId": "vis_api_authorize_inspection_media", "summary": "Authorize Inspection Media", "parameters": [{"in": "path", "name": "sol_id", "schema": {"title": "Sol Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Sets the cookies to access the CDN for a given inspection service order line ID.", "tags": ["vis.inspections"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/pointclouds/{id}/{data_file}/": {"get": {"operationId": "vis_api_get_pointcloud_data_file", "summary": "Fetch data file associated with a given pointcloud ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "data_file", "schema": {"title": "Data File", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK"}}, "description": "Fetch data file associated with a given pointcloud ID.", "tags": ["vis.pointclouds"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/rosbags/{id}/distances/": {"get": {"operationId": "vis_api_get_rosbag_distances", "summary": "Fetch distances associated with a given rosbag ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RosbagBlobDistancesSchema"}}}}, "202": {"description": "Accepted"}}, "description": "Fetch distances associated with a given rosbag ID.", "tags": ["vis.rosbags"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/rosbags/{id}/ranges/{qr_code}/": {"get": {"operationId": "vis_api_get_rosbag_ranges", "summary": "Fetch ranges associated with a given rosbag ID and QR code.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "qr_code", "schema": {"title": "Qr Code", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RosbagBlobRangesSchema"}}}}}, "description": "Fetch ranges associated with a given rosbag ID and QR code.", "tags": ["vis.rosbags"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/video-files/{id}/anomaly/": {"post": {"operationId": "vis_api_post_video_file_anomaly", "summary": "Create an anomaly associated with a given video file ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyResponse"}}}}}, "description": "Create an anomaly associated with a given video file ID.", "tags": ["vis.video-files"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/video-files/{id}/rosbags/": {"get": {"operationId": "vis_api_get_video_file_rosbags", "summary": "Fetch rosbags associated with a given video file ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RosbagSchema"}, "title": "Response", "type": "array"}}}}}, "description": "Fetch rosbags associated with a given video file ID.", "tags": ["vis.video-files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/video-files/{id}/pointclouds/": {"get": {"operationId": "vis_api_get_video_file_pointclouds", "summary": "Fetch pointclouds associated with a given video file ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RosbagBlobSchema"}, "title": "Response", "type": "array"}}}}}, "description": "Fetch pointclouds associated with a given video file ID.", "tags": ["vis.video-files"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/root-photos/{id}/anomaly/": {"post": {"operationId": "vis_api_post_root_photo_anomaly", "summary": "Create an anomaly associated with a given root photo ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyResponse"}}}}}, "description": "Create an anomaly associated with a given root photo ID.", "tags": ["vis.root-photos"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/external-photos/{id}/anomaly/": {"post": {"operationId": "vis_api_post_external_photo_anomaly", "summary": "Create an anomaly associated with a given external photo ID.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyResponse"}}}}}, "description": "Create an anomaly associated with a given external photo ID.", "tags": ["vis.external-photos"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/ai-anomalies": {"post": {"operationId": "vis_api_post_ai_anomaly", "summary": "Register an AI-detected defect (REST twin of registerAiDefect).", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalySchema"}}}}}, "description": "Register an AI-detected defect, creating core.Anomaly + vis.AiAnomaly atomically.\n\nShares the ``vis.anomalies.register_ai_defect`` service with the GraphQL\n``registerAiDefect`` mutation, so behaviour is identical on both surfaces.", "tags": ["vis.ai-anomalies"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalyRegisterSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/ai-anomalies/{id}/source-object": {"patch": {"operationId": "vis_api_patch_ai_anomaly_source_object", "summary": "Set the source photo/video reference on an AI anomaly.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalySchema"}}}}}, "description": "Backfill ``core.Anomaly.source_object`` for a pushed AI defect.\n\nThe drone pipeline registers a defect before the portal has registered its\nsource photo, so the reference is set once that id exists. Narrow by design:\nit touches the generic-FK pair only, and only on AI-registered anomalies.", "tags": ["vis.ai-anomalies"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalySourceObjectSchema"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/ai-anomalies/{id}": {"get": {"operationId": "vis_api_get_ai_anomaly", "summary": "Fetch an AI anomaly by its own primary key.", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalySchema"}}}}}, "description": "Fetch a vis.AiAnomaly by its own primary key.", "tags": ["vis.ai-anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/ai-anomalies/by-defect-id/{defect_id}": {"get": {"operationId": "vis_api_get_ai_anomaly_by_defect_id", "summary": "Fetch an AI anomaly by the pipeline's inference_defect_id.", "parameters": [{"in": "path", "name": "defect_id", "schema": {"title": "Defect Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalySchema"}}}}}, "description": "Fetch a vis.AiAnomaly by the AI pipeline's inference_defect_id.", "tags": ["vis.ai-anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/vis/v1/ai-anomalies/by-defect-uid/{defect_uid}": {"get": {"operationId": "vis_api_get_ai_anomaly_by_defect_uid", "summary": "Fetch an AI anomaly by defect_uid (external defects).", "parameters": [{"in": "path", "name": "defect_uid", "schema": {"title": "Defect Uid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AiAnomalySchema"}}}}}, "description": "Fetch a vis.AiAnomaly by defect_uid (external detections).", "tags": ["vis.ai-anomalies"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns/with-scope": {"post": {"operationId": "client_work_management_endpoints_campaigns_create_campaign_with_scope", "summary": "Create Campaign With Scope", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignWithScopeResponse"}}}}}, "description": "Atomically create a Campaign + one WorkPackage per selected park.\n\nProductionises AeroCore's ``create-campaign-with-scope`` Track-2 shim: what\nwas a best-effort sequence of ``POST /campaigns`` + N ``POST /work-packages``\nwith cleanup-on-failure is now a single transaction (no orphans possible).", "tags": ["work-management.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignWithScopeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns": {"get": {"operationId": "list_campaigns", "summary": "List Campaigns", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CampaignResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["work-management.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_campaign", "summary": "Create Campaign", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignResponse"}}}}}, "description": "Create a new item.", "tags": ["work-management.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns/{id}": {"get": {"operationId": "get_campaign", "summary": "Get Campaign", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["work-management.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_campaign", "summary": "Update Campaign", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignResponse"}}}}}, "description": "Update an item.", "tags": ["work-management.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CampaignUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_campaign", "summary": "Delete Campaign", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["work-management.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns/{id}/comments": {"post": {"operationId": "client_work_management_endpoints_campaigns_add_comment", "summary": "Add Comment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentResponse"}}}}}, "tags": ["work-management.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns/{id}/comments/{comment_id}": {"delete": {"operationId": "client_work_management_endpoints_campaigns_delete_comment", "summary": "Delete Comment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns/{id}/attach": {"post": {"operationId": "client_work_management_endpoints_campaigns_attach_file", "summary": "Attach File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentResponse"}}}}}, "tags": ["work-management.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/campaigns/{id}/detach/{storage_id}": {"delete": {"operationId": "client_work_management_endpoints_campaigns_detach_file", "summary": "Detach File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/with-scope": {"post": {"operationId": "client_work_management_endpoints_work_packages_create_work_packages_with_scope", "summary": "Create Work Packages With Scope", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageWithScopeResponse"}}}}}, "description": "Atomically create one WP per selected turbine, or one WP for a whole park.", "tags": ["work-management.work-packages"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageWithScopeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/with-campaigns": {"get": {"operationId": "client_work_management_endpoints_work_packages_list_work_packages_with_campaigns", "summary": "List Work Packages With Campaigns", "parameters": [{"in": "query", "name": "active_only", "schema": {"default": true, "title": "Active Only", "type": "boolean"}, "required": false}, {"in": "query", "name": "turbine_ids", "schema": {"default": "", "title": "Turbine Ids", "type": "string"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackagesWithCampaignsResponse"}}}}}, "description": "Turbines linked to campaign-scoped work packages (active-campaigns widget).", "tags": ["work-management.work-packages"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages": {"get": {"operationId": "list_work_packages", "summary": "List Work Packages", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "campaign_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "required": false}, {"in": "query", "name": "vendor_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "required": false}, {"in": "query", "name": "site_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "required": false}, {"in": "query", "name": "active_only", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Active Only"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/WorkPackageResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["work-management.work-packages"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_work_package", "summary": "Create Work Package", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageResponse"}}}}}, "description": "Create a new item.", "tags": ["work-management.work-packages"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/{id}": {"get": {"operationId": "get_work_package", "summary": "Get Work Package", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["work-management.work-packages"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_work_package", "summary": "Update Work Package", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageResponse"}}}}}, "description": "Update an item.", "tags": ["work-management.work-packages"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WorkPackageUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_work_package", "summary": "Delete Work Package", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["work-management.work-packages"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/{id}/comments": {"post": {"operationId": "client_work_management_endpoints_work_packages_add_comment", "summary": "Add Comment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentResponse"}}}}}, "tags": ["work-management.work-packages"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/{id}/comments/{comment_id}": {"delete": {"operationId": "client_work_management_endpoints_work_packages_delete_comment", "summary": "Delete Comment", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.work-packages"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/{id}/attach": {"post": {"operationId": "client_work_management_endpoints_work_packages_attach_file", "summary": "Attach File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentResponse"}}}}}, "tags": ["work-management.work-packages"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-packages/{id}/detach/{storage_id}": {"delete": {"operationId": "client_work_management_endpoints_work_packages_detach_file", "summary": "Detach File", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.work-packages"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders": {"get": {"operationId": "client_work_management_endpoints_client_work_orders_list_work_orders", "summary": "List Client Work Orders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "task_type", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Task Type"}, "required": false}, {"in": "query", "name": "priority", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "required": false}, {"in": "query", "name": "vendor_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "required": false}, {"in": "query", "name": "campaign_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "required": false}, {"in": "query", "name": "work_package_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Package Id"}, "required": false}, {"in": "query", "name": "anomaly_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "required": false}, {"in": "query", "name": "site_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "required": false}, {"in": "query", "name": "turbine_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "required": false}, {"in": "query", "name": "turbine_component_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "required": false}, {"in": "query", "name": "unassigned", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Unassigned"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/ClientWorkOrderResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["work-management.client-work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "client_work_management_endpoints_client_work_orders_create_work_order", "summary": "Create Client Work Order", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientWorkOrderResponse"}}}}}, "tags": ["work-management.client-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientWorkOrderCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/{id}": {"get": {"operationId": "client_work_management_endpoints_client_work_orders_get_work_order", "summary": "Get Client Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientWorkOrderResponse"}}}}}, "tags": ["work-management.client-work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "client_work_management_endpoints_client_work_orders_update_work_order", "summary": "Update Client Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientWorkOrderResponse"}}}}}, "tags": ["work-management.client-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ClientWorkOrderUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "client_work_management_endpoints_client_work_orders_delete_work_order", "summary": "Delete Client Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.client-work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/complete": {"post": {"operationId": "client_work_management_endpoints_client_work_orders_complete_work_orders", "summary": "Complete Work Orders (and cascade linked anomalies)", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CompleteWorkOrdersResponse"}}}}}, "description": "Atomically complete each work order and advance its linked anomaly.\n\nProductionises AECP-333 (pairs the portal's AECP-329 two-call orchestration):\nper work order, in one transaction, set ``status=completed`` (stamping\n``completed_date``) and \u2014 if it has a linked anomaly \u2014 advance that anomaly's\n``stage`` -> ``RESOLUTION_COMPLETE`` (which recomputes ``resolution_status``\n-> ``RESOLVED``). A WO with no anomaly completes with ``cascade=\"none\"``; if a\nWO's cascade fails, that WO rolls back (``cascade=\"failed\"``) while the others\nstill succeed. Gated on work-management-manage; the cascade is RLS-scoped, so\nit can only advance anomalies the caller's customer owns.", "tags": ["work-management.client-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CompleteWorkOrdersPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/{id}/comments": {"post": {"operationId": "client_work_management_endpoints_client_work_orders_add_comment", "summary": "Add Comment to Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentResponse"}}}}}, "tags": ["work-management.client-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/{id}/comments/{comment_id}": {"delete": {"operationId": "client_work_management_endpoints_client_work_orders_delete_comment", "summary": "Delete Comment from Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.client-work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/{id}/attach": {"post": {"operationId": "client_work_management_endpoints_client_work_orders_attach_file", "summary": "Attach File to Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentResponse"}}}}}, "tags": ["work-management.client-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/{id}/detach/{storage_id}": {"delete": {"operationId": "client_work_management_endpoints_client_work_orders_detach_file", "summary": "Detach File from Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.client-work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/client-work-orders/{id}/apply-template": {"post": {"operationId": "client_work_management_endpoints_client_work_orders_apply_template", "summary": "Apply Activity Template to Work Order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CwmActivityResponse"}, "title": "Response", "type": "array"}}}}}, "tags": ["work-management.client-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmApplyTemplatePayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities": {"get": {"operationId": "client_work_management_endpoints_activities_list_activities", "summary": "List Activities", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "client_work_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Client Work Order Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CwmActivityResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "tags": ["work-management.activities"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "client_work_management_endpoints_activities_create_activity", "summary": "Create Activity", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityResponse"}}}}}, "tags": ["work-management.activities"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities/{id}": {"get": {"operationId": "client_work_management_endpoints_activities_get_activity", "summary": "Get Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityResponse"}}}}}, "tags": ["work-management.activities"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "put": {"operationId": "client_work_management_endpoints_activities_update_activity", "summary": "Update Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityResponse"}}}}}, "tags": ["work-management.activities"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "client_work_management_endpoints_activities_delete_activity", "summary": "Delete Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.activities"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities/reorder": {"post": {"operationId": "client_work_management_endpoints_activities_reorder_activities", "summary": "Reorder Activities", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.activities"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityReorderPayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities/{id}/comments": {"post": {"operationId": "client_work_management_endpoints_activities_add_comment", "summary": "Add Comment to Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentResponse"}}}}}, "tags": ["work-management.activities"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CommentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities/{id}/comments/{comment_id}": {"delete": {"operationId": "client_work_management_endpoints_activities_delete_comment", "summary": "Delete Comment from Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "comment_id", "schema": {"title": "Comment Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.activities"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities/{id}/attach": {"post": {"operationId": "client_work_management_endpoints_activities_attach_file", "summary": "Attach File to Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentResponse"}}}}}, "tags": ["work-management.activities"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AttachmentCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/cwo-activities/{id}/detach/{storage_id}": {"delete": {"operationId": "client_work_management_endpoints_activities_detach_file", "summary": "Detach File from Activity", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "storage_id", "schema": {"title": "Storage Id", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "tags": ["work-management.activities"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/activity-templates": {"get": {"operationId": "list_activity_templates", "summary": "List Activity Templates", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CwmActivityTemplateResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["work-management.activity-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_activity_template", "summary": "Create Activity Template", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityTemplateResponse"}}}}}, "description": "Create a new item.", "tags": ["work-management.activity-templates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityTemplateCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/activity-templates/{id}": {"get": {"operationId": "get_activity_template", "summary": "Get Activity Template", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityTemplateResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["work-management.activity-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_activity_template", "summary": "Update Activity Template", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityTemplateResponse"}}}}}, "description": "Update an item.", "tags": ["work-management.activity-templates"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmActivityTemplateUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_activity_template", "summary": "Delete Activity Template", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["work-management.activity-templates"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/vendors": {"get": {"operationId": "list_vendors", "summary": "List Vendors", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CwmVendorResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["work-management.vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_vendor", "summary": "Create Vendor", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmVendorResponse"}}}}}, "description": "Create a new item.", "tags": ["work-management.vendors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmVendorCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/vendors/{id}": {"get": {"operationId": "get_vendor", "summary": "Get Vendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmVendorResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["work-management.vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_vendor", "summary": "Update Vendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmVendorResponse"}}}}}, "description": "Update an item.", "tags": ["work-management.vendors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmVendorUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_vendor", "summary": "Delete Vendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["work-management.vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/task-types": {"get": {"operationId": "list_task_types", "summary": "List Task Types", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "name", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/CwmTaskTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["work-management.task-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_task_type", "summary": "Create Task Type", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmTaskTypeResponse"}}}}}, "description": "Create a new item.", "tags": ["work-management.task-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmTaskTypeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/task-types/{id}": {"get": {"operationId": "get_task_type", "summary": "Get Task Type", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmTaskTypeResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["work-management.task-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_task_type", "summary": "Update Task Type", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmTaskTypeResponse"}}}}}, "description": "Update an item.", "tags": ["work-management.task-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CwmTaskTypeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_task_type", "summary": "Delete Task Type", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["work-management.task-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/statuses": {"get": {"operationId": "client_work_management_endpoints_statuses_get_statuses", "summary": "Get Status Options", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StatusesResponse"}}}}}, "tags": ["work-management.statuses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/work-orders": {"post": {"operationId": "client_work_management_endpoints_anomaly_client_work_orders_create_anomaly_work_orders", "summary": "Create Work Orders for Anomalies", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyWorkOrdersResponse"}}}}}, "tags": ["work-management.anomaly-work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyWorkOrdersCreatePayload"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/work-management/anomalies/{anomaly_id}/work-orders": {"get": {"operationId": "client_work_management_endpoints_anomaly_client_work_orders_get_anomaly_work_orders", "summary": "Get Work Orders for Anomaly", "parameters": [{"in": "path", "name": "anomaly_id", "schema": {"title": "Anomaly Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AnomalyWorkOrdersResponse"}}}}}, "tags": ["work-management.anomaly-work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/campaigns": {"get": {"operationId": "list_campaigns", "summary": "List Campaigns", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningCampaignResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_campaign", "summary": "Create Campaign", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCampaignResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCampaignCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/campaigns/{id}": {"get": {"operationId": "get_campaign", "summary": "Get Campaign", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCampaignResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_campaign", "summary": "Update Campaign", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCampaignResponse"}}}}}, "description": "Update an item.", "tags": ["planning.campaigns"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCampaignUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_campaign", "summary": "Delete Campaign", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.campaigns"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/projects": {"get": {"operationId": "list_projects", "summary": "List Projects", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "campaign_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningProjectResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_project", "summary": "Create Project", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningProjectResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningProjectCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/projects/{id}": {"get": {"operationId": "get_project", "summary": "Get Project", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningProjectResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_project", "summary": "Update Project", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningProjectResponse"}}}}}, "description": "Update an item.", "tags": ["planning.projects"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningProjectUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_project", "summary": "Delete Project", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.projects"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/services": {"get": {"operationId": "list_services", "summary": "List Services", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "core_service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Service Id"}, "required": false}, {"in": "query", "name": "active", "schema": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Active"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningServiceResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_service", "summary": "Create Service", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/services/{id}": {"get": {"operationId": "get_service", "summary": "Get Service", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_service", "summary": "Update Service", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceResponse"}}}}}, "description": "Update an item.", "tags": ["planning.services"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_service", "summary": "Delete Service", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.services"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/customer-vendors": {"get": {"operationId": "list_customervendors", "summary": "List CustomerVendors", "parameters": [{"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "vendor_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningCustomerVendorResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.customer-vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_customervendor", "summary": "Create CustomerVendor", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCustomerVendorResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.customer-vendors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCustomerVendorCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/customer-vendors/{id}": {"get": {"operationId": "get_customervendor", "summary": "Get CustomerVendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCustomerVendorResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.customer-vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_customervendor", "summary": "Update CustomerVendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCustomerVendorResponse"}}}}}, "description": "Update an item.", "tags": ["planning.customer-vendors"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningCustomerVendorUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_customervendor", "summary": "Delete CustomerVendor", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.customer-vendors"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/service-orders/{id}/anomalies": {"post": {"operationId": "planning_endpoints_service_order_anomalies_link_anomalies", "summary": "Link anomalies to a service order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderResponse"}}}}}, "description": "Appends the given anomaly ids to the service order's linked set. Idempotent: an anomaly already actively linked is left untouched (no duplicate row).", "tags": ["planning"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderAnomalyLinkRequest"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/service-orders/{id}/anomalies/{anomaly_id}": {"delete": {"operationId": "planning_endpoints_service_order_anomalies_unlink_anomaly", "summary": "Unlink an anomaly from a service order", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}, {"in": "path", "name": "anomaly_id", "schema": {"title": "Anomaly Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderResponse"}}}}}, "description": "Remove a single anomaly link from a service order.", "tags": ["planning"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/service-orders": {"get": {"operationId": "list_serviceorders", "summary": "List ServiceOrders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "project_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "required": false}, {"in": "query", "name": "service_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "required": false}, {"in": "query", "name": "vendor_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningServiceOrderResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_serviceorder", "summary": "Create ServiceOrder", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/service-orders/{id}": {"get": {"operationId": "get_serviceorder", "summary": "Get ServiceOrder", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_serviceorder", "summary": "Update ServiceOrder", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderResponse"}}}}}, "description": "Update an item.", "tags": ["planning.service-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningServiceOrderUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_serviceorder", "summary": "Delete ServiceOrder", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.service-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/work-order-types": {"get": {"operationId": "list_workordertypes", "summary": "List WorkOrderTypes", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningWorkOrderTypeResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.work-order-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_workordertype", "summary": "Create WorkOrderType", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderTypeResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.work-order-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderTypeCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/work-order-types/{id}": {"get": {"operationId": "get_workordertype", "summary": "Get WorkOrderType", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderTypeResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.work-order-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_workordertype", "summary": "Update WorkOrderType", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderTypeResponse"}}}}}, "description": "Update an item.", "tags": ["planning.work-order-types"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderTypeUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_workordertype", "summary": "Delete WorkOrderType", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.work-order-types"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/work-orders": {"get": {"operationId": "list_workorders", "summary": "List WorkOrders", "parameters": [{"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "sort", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "customer_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "required": false}, {"in": "query", "name": "service_order_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "required": false}, {"in": "query", "name": "type_id", "schema": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Type Id"}, "required": false}, {"in": "query", "name": "paginate", "schema": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "required": false, "description": "Enable pagination (false returns all results)"}, {"in": "query", "name": "page", "schema": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "required": false, "description": "Page number"}, {"in": "query", "name": "page_size", "schema": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "required": false, "description": "Number of items per page"}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/PlanningWorkOrderResponse"}, "title": "Response", "type": "array"}}}}, "400": {"description": "Bad Request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}}, "description": "List all items with optional search, sorting, and pagination.", "tags": ["planning.work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "post": {"operationId": "create_workorder", "summary": "Create WorkOrder", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderResponse"}}}}}, "description": "Create a new item.", "tags": ["planning.work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderCreate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/work-orders/{id}": {"get": {"operationId": "get_workorder", "summary": "Get WorkOrder", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderResponse"}}}}}, "description": "Get a single item by ID.", "tags": ["planning.work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "patch": {"operationId": "update_workorder", "summary": "Update WorkOrder", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderResponse"}}}}}, "description": "Update an item.", "tags": ["planning.work-orders"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningWorkOrderUpdate"}}}, "required": true}, "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}, "delete": {"operationId": "delete_workorder", "summary": "Delete WorkOrder", "parameters": [{"in": "path", "name": "id", "schema": {"title": "Id", "type": "integer"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Success"}}}}}, "description": "Soft delete an item.", "tags": ["planning.work-orders"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}, "/api/planning/v1/statuses": {"get": {"operationId": "planning_endpoints_statuses_get_statuses", "summary": "Get planning status catalogue", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PlanningStatusesResponse"}}}}}, "description": "Return the authoritative planning status catalogue.\n\nCampaign, Project, ServiceOrder and WorkOrder currently share the single\nunified ``PlanningStatus`` enum, so every per-entity list is identical.", "tags": ["planning.statuses"], "security": [{"APIKeyAuth": []}, {"CookieAuth": []}]}}}, "components": {"schemas": {"Success": {"additionalProperties": false, "description": "Schema returned for successful operations.\n\nThe `success` field is always ``true`` in this schema. Failed operations are\nrepresented by the :class:`Error` schema instead, so a ``false`` value does\nnot occur in practice. The field is included for consistency across responses\nand to make the contract explicit for clients.", "properties": {"success": {"default": true, "description": "Always true for this schema. Errors are represented by a separate Error schema, so false is never returned.", "title": "Success", "type": "boolean"}}, "title": "Success", "type": "object"}, "Error": {"additionalProperties": false, "description": "Error response schema.", "properties": {"code": {"$ref": "#/components/schemas/ErrorCode"}, "message": {"title": "Message", "type": "string"}}, "required": ["code", "message"], "title": "Error", "type": "object"}, "ErrorCode": {"description": "Error codes for API errors.", "enum": ["validation", "server", "auth", "unknown", "external", "generic"], "title": "ErrorCode", "type": "string"}, "Authenticate": {"additionalProperties": false, "description": "Schema for authentication.", "properties": {"token": {"description": "Authentication token.", "title": "Token", "type": "string"}, "token_type": {"$ref": "#/components/schemas/TokenType", "description": "Token type."}, "impersonate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Optional user id to impersonate. Only honored for JWT auth and requires the caller to hold `auth.impersonate`. Pass `null` (or omit) to clear an existing impersonation from the session.", "title": "Impersonate Id"}}, "required": ["token", "token_type"], "title": "Authenticate", "type": "object"}, "TokenType": {"description": "Token type enum.", "enum": ["Bearer", "JWT", "PWT"], "title": "TokenType", "type": "string"}, "ClientLoginResponse": {"additionalProperties": false, "description": "Response schema for client login, returning access token and project ID.", "properties": {"access_token": {"description": "Signed PWT access token", "title": "Access Token", "type": "string"}, "project_id": {"description": "UUID of the authenticated project", "title": "Project Id", "type": "string"}}, "required": ["access_token", "project_id"], "title": "ClientLoginResponse", "type": "object"}, "ClientLoginRequest": {"additionalProperties": false, "description": "Request schema for client login via project password.", "properties": {"password": {"description": "Project password", "title": "Password", "type": "string"}}, "required": ["password"], "title": "ClientLoginRequest", "type": "object"}, "PermissionCodename": {"description": "All supported permission codenames in the system.", "enum": ["auth.admin", "auth.impersonate", "auth.project_manager", "auth.regular_user", "auth.query_basic_graphql", "auth.mutate_basic_graphql", "auth.sales_manager_usa", "auth.sales_manager_eu", "auth.cco", "auth.co_watcher", "permissions.hse_reviewer", "permissions.rams_template_manage", "permissions.manage_customer_custom_field_values", "permissions.announce_notification_event", "permissions.send_team_request_to_planner", "permissions.approve_team_request_slot", "permissions.approve_set_request", "permissions.mark_ready_set_request", "permissions.mark_picked_up_set_request", "permissions.receive_set_request_mro_notification", "permissions.receive_set_request_it_notification", "permissions.confirm_set_request_it", "permissions.confirm_set_request_ppe", "permissions.receive_set_request_ppe_notification", "permissions.manage_set_demob", "permissions.receive_set_demob_it_notification", "permissions.receive_set_demob_mro_notification", "permissions.receive_planner_handoff_notification", "permissions.approve_scope_change_qc", "permissions.approve_scope_change_sales", "permissions.approve_scope_change_pm", "auth.bto_viewer", "auth.bto_supervisor", "projects.is_bto_watcher", "permissions.pwt_access", "auth.technician_user", "auth.vis_qc", "permissions.view_all", "permissions.view_all_vehicle_fleet_assignments", "permissions.manage_all_vehicle_fleet_assignments", "auth.payroll_manager", "permissions.manage_customer_users", "permissions.customer_basic_access", "permissions.customer_manage_access_control", "permissions.customer_view_fleet", "permissions.customer_view_services", "permissions.customer_manage_services", "permissions.customer_view_anomalies", "permissions.customer_manage_anomalies", "permissions.customer_view_vis", "permissions.customer_manage_vis", "permissions.customer_view_projects", "permissions.customer_view_reports", "permissions.customer_manage_reports", "permissions.customer_view_analytics", "permissions.customer_view_scope_changes", "permissions.customer_manage_scope_changes", "permissions.customer_view_work_management", "permissions.customer_manage_work_management", "permissions.customer_manage_terms_of_service", "permissions.customer_view_workorders", "permissions.customer_manage_workorders", "permissions.customer_cir_submit", "permissions.sales_form_app", "permissions.sales_pipeline_app", "permissions.project_tasks_dashboard_app", "permissions.aeroplan_app", "permissions.price_matrix_app", "permissions.data_operations_app", "permissions.mobilisation_app", "permissions.execution_app", "permissions.my_projects_app", "permissions.aeromro_app", "permissions.cru_qc", "permissions.manage_logistics", "permissions.manage_reporting_requirements", "permissions.force_complete_project", "permissions.remove_prejob_certificates", "permissions.xapp_data_operations_perform_qc", "permissions.xapp_data_operations_operate", "auth.broe"], "title": "PermissionCodename", "type": "string"}, "User": {"additionalProperties": false, "description": "Schema for user details.", "properties": {"id": {"title": "Id", "type": "integer"}, "sso_uuid": {"title": "Sso Uuid", "type": "string"}, "email": {"title": "Email", "type": "string"}, "first_name": {"title": "First Name", "type": "string"}, "last_name": {"title": "Last Name", "type": "string"}, "picture_url": {"title": "Picture Url", "type": "string"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "customers": {"default": [], "items": {"$ref": "#/components/schemas/UserCustomer"}, "title": "Customers", "type": "array"}, "phone": {"default": "", "title": "Phone", "type": "string"}, "user_type": {"$ref": "#/components/schemas/UserType"}, "roles": {"items": {"type": "string"}, "title": "Roles", "type": "array"}, "permissions": {"items": {"$ref": "#/components/schemas/PermissionCodename"}, "title": "Permissions", "type": "array"}, "impersonate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Impersonate Id"}, "date_joined": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Account creation timestamp (Django auth user date_joined).", "title": "Date Joined"}}, "required": ["id", "sso_uuid", "email", "first_name", "last_name", "picture_url", "user_type", "roles", "permissions"], "title": "User", "type": "object"}, "UserCustomer": {"additionalProperties": false, "description": "Customer the user has access to, with their roles at that customer.", "properties": {"id": {"title": "Id", "type": "integer"}, "organisation": {"title": "Organisation", "type": "string"}, "role": {"default": [], "items": {"type": "string"}, "title": "Role", "type": "array"}, "status": {"default": "ACTIVE", "title": "Status", "type": "string"}, "invite_expires_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Invite Expires At"}}, "required": ["id", "organisation"], "title": "UserCustomer", "type": "object"}, "UserType": {"description": "User classification based on customer relationships.", "enum": ["INTERNAL", "CUSTOMER"], "title": "UserType", "type": "string"}, "ManufacturerQueryParams": {"additionalProperties": false, "description": "Query parameters for manufacturers endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "has_models": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter manufacturers that have at least one turbine or component model", "title": "Has Models"}}, "title": "ManufacturerQueryParams", "type": "object"}, "PaginationInput": {"properties": {"paginate": {"default": true, "description": "Enable pagination (false returns all results)", "title": "Paginate", "type": "boolean"}, "page": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "page_size": {"default": 50, "description": "Number of items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}}, "title": "PaginationInput", "type": "object"}, "ManufacturerResponse": {"additionalProperties": false, "description": "Schema for Manufacturer response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Entity ID", "title": "Id", "type": "integer"}, "name": {"description": "Entity name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "name"], "title": "ManufacturerResponse", "type": "object"}, "ManufacturerCreate": {"additionalProperties": false, "description": "Schema for creating a Manufacturer.", "properties": {"name": {"description": "Entity name", "minLength": 1, "title": "Name", "type": "string"}}, "required": ["name"], "title": "ManufacturerCreate", "type": "object"}, "ManufacturerUpdate": {"additionalProperties": false, "description": "Schema for updating a Manufacturer.", "properties": {"name": {"description": "Entity name", "minLength": 1, "title": "Name", "type": "string"}}, "title": "ManufacturerUpdate", "type": "object"}, "ComponentModelQueryParams": {"additionalProperties": false, "description": "Query parameters for component models endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component type ID", "title": "Component Type Id"}}, "title": "ComponentModelQueryParams", "type": "object"}, "ComponentModelResponse": {"additionalProperties": false, "description": "Schema for ManufacturerComponentModel response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Component model ID", "title": "Id", "type": "integer"}, "name": {"description": "Component model name", "title": "Name", "type": "string"}, "manufacturer": {"$ref": "#/components/schemas/ManufacturerObject", "description": "Manufacturer information"}, "component_type": {"$ref": "#/components/schemas/ComponentTypeObject", "description": "Component type information"}, "length": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Length in meters", "title": "Length"}, "crawler_range": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Crawler range in meters", "title": "Crawler Range"}, "blade_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade construction type", "title": "Blade Type"}}, "required": ["updated_at", "id", "name", "manufacturer", "component_type"], "title": "ComponentModelResponse", "type": "object"}, "ComponentTypeObject": {"additionalProperties": false, "description": "Nested component type object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "field_list": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Field List"}}, "required": ["id", "name"], "title": "ComponentTypeObject", "type": "object"}, "ManufacturerObject": {"additionalProperties": false, "description": "Nested manufacturer object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ManufacturerObject", "type": "object"}, "ComponentModelCreate": {"additionalProperties": false, "description": "Schema for creating a ManufacturerComponentModel.", "properties": {"name": {"description": "Component model name", "minLength": 1, "title": "Name", "type": "string"}, "manufacturer_id": {"description": "Manufacturer ID", "title": "Manufacturer Id", "type": "integer"}, "component_type_id": {"description": "Component type ID", "title": "Component Type Id", "type": "integer"}, "length": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Length in meters", "title": "Length"}, "crawler_range": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Crawler range in meters", "title": "Crawler Range"}, "blade_type": {"anyOf": [{"enum": ["BOX_SPAR", "SINGLE_SHEAR_WEB", "DOUBLE_SHEAR_WEB", "TRIPLE_SHEAR_WEB", "QUADRUPLE_SHEAR_WEB"], "type": "string"}, {"type": "null"}], "description": "Blade construction type", "title": "Blade Type"}}, "required": ["name", "manufacturer_id", "component_type_id"], "title": "ComponentModelCreate", "type": "object"}, "ComponentModelUpdate": {"additionalProperties": false, "description": "Schema for updating a ManufacturerComponentModel.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Component model name", "title": "Name"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID", "title": "Component Type Id"}, "length": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Length in meters", "title": "Length"}, "crawler_range": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Crawler range in meters", "title": "Crawler Range"}, "blade_type": {"anyOf": [{"enum": ["BOX_SPAR", "SINGLE_SHEAR_WEB", "DOUBLE_SHEAR_WEB", "TRIPLE_SHEAR_WEB", "QUADRUPLE_SHEAR_WEB"], "type": "string"}, {"type": "null"}], "description": "Blade construction type", "title": "Blade Type"}}, "title": "ComponentModelUpdate", "type": "object"}, "TurbineModelQueryParams": {"additionalProperties": false, "description": "Query parameters for turbine models endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}}, "title": "TurbineModelQueryParams", "type": "object"}, "TurbineModelResponse": {"additionalProperties": false, "description": "Schema for TurbineModel response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Turbine model ID", "title": "Id", "type": "integer"}, "name": {"description": "Turbine model name", "title": "Name", "type": "string"}, "manufacturer": {"$ref": "#/components/schemas/ManufacturerObject", "description": "Manufacturer details"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "center_to_root_offset": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Centre-to-root offset (hub radius) in metres \u2014 distance_to_hub_centre = distance_to_root + this. NULL means unconfigured.", "title": "Center To Root Offset"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "double_receptors": {"description": "Has double receptors", "title": "Double Receptors", "type": "boolean"}, "hv_double_receptors": {"description": "Has HV double receptors", "title": "Hv Double Receptors", "type": "boolean"}}, "required": ["updated_at", "id", "name", "manufacturer", "double_receptors", "hv_double_receptors"], "title": "TurbineModelResponse", "type": "object"}, "TurbineModelCreate": {"additionalProperties": false, "description": "Schema for creating a TurbineModel.", "properties": {"name": {"description": "Turbine model name", "minLength": 1, "title": "Name", "type": "string"}, "manufacturer_id": {"description": "Manufacturer ID", "title": "Manufacturer Id", "type": "integer"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "center_to_root_offset": {"anyOf": [{"exclusiveMinimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Centre-to-root offset (hub radius) in metres \u2014 distance_to_hub_centre = distance_to_root + this. NULL means unconfigured.", "title": "Center To Root Offset"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "double_receptors": {"default": false, "description": "Has double receptors", "title": "Double Receptors", "type": "boolean"}, "hv_double_receptors": {"default": false, "description": "Has HV double receptors", "title": "Hv Double Receptors", "type": "boolean"}}, "required": ["name", "manufacturer_id"], "title": "TurbineModelCreate", "type": "object"}, "TurbineModelUpdate": {"additionalProperties": false, "description": "Schema for updating a TurbineModel.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Turbine model name", "title": "Name"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "center_to_root_offset": {"anyOf": [{"exclusiveMinimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Centre-to-root offset (hub radius) in metres \u2014 distance_to_hub_centre = distance_to_root + this. NULL means unconfigured.", "title": "Center To Root Offset"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "double_receptors": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Has double receptors", "title": "Double Receptors"}, "hv_double_receptors": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Has HV double receptors", "title": "Hv Double Receptors"}}, "title": "TurbineModelUpdate", "type": "object"}, "QueryParams": {"additionalProperties": false, "description": "Common query parameters for list endpoints.\n\nNote: page and page_size are handled by the @paginate decorator from builderapi.utils.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "QueryParams", "type": "object"}, "ComponentTypeResponse": {"additionalProperties": false, "description": "Schema for ComponentType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Entity ID", "title": "Id", "type": "integer"}, "name": {"description": "Entity name", "title": "Name", "type": "string"}, "parent_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent component type ID", "title": "Parent Id"}, "field_list": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "List of fields for this component type", "title": "Field List"}}, "required": ["updated_at", "id", "name"], "title": "ComponentTypeResponse", "type": "object"}, "RobotSetQueryParams": {"additionalProperties": false, "description": "Query parameters for robot sets endpoint.\n\nNote: page and page_size are handled by the @paginate decorator from builderapi.utils.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "services": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service IDs (comma-separated, e.g., '1,2,3')", "title": "Services"}}, "title": "RobotSetQueryParams", "type": "object"}, "RobotSetResponse": {"additionalProperties": false, "description": "Schema for RobotSet response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Robot set ID", "title": "Id", "type": "integer"}, "name": {"description": "Robot set name", "title": "Name", "type": "string"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set code", "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set description", "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Lifecycle: REQUESTED | IN_PRODUCTION | IN_USE | RETIRED", "title": "Status"}, "netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID", "title": "Netsuite Id"}, "maintainx_asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "MaintainX asset ID (read-only; the link is owned by maintainx.Asset)", "title": "Maintainx Asset Id"}, "services": {"description": "Associated services", "items": {"$ref": "#/components/schemas/RobotSetServiceNestedResponse"}, "title": "Services", "type": "array"}}, "required": ["updated_at", "id", "name"], "title": "RobotSetResponse", "type": "object"}, "RobotSetServiceNestedResponse": {"additionalProperties": false, "description": "Nested response for service in robot set response (no timestamps in nested objects).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "RobotSetServiceNestedResponse", "type": "object"}, "RobotSetCreate": {"additionalProperties": false, "description": "Schema for creating a RobotSet.", "properties": {"name": {"description": "Entity name", "minLength": 1, "title": "Name", "type": "string"}, "code": {"anyOf": [{"maxLength": 30, "type": "string"}, {"type": "null"}], "description": "Robot set code (unique among active sets)", "title": "Code"}, "description": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "description": "Robot set description (unique among active sets)", "title": "Description"}, "status": {"anyOf": [{"enum": ["REQUESTED", "IN_PRODUCTION", "IN_USE", "RETIRED"], "type": "string"}, {"type": "null"}], "description": "Lifecycle: REQUESTED | IN_PRODUCTION | IN_USE | RETIRED", "title": "Status"}, "service_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "List of service IDs to associate with the robot set", "title": "Service Ids"}}, "required": ["name"], "title": "RobotSetCreate", "type": "object"}, "RobotSetUpdate": {"additionalProperties": false, "description": "Schema for updating a RobotSet.", "properties": {"name": {"description": "Entity name", "minLength": 1, "title": "Name", "type": "string"}, "code": {"anyOf": [{"maxLength": 30, "type": "string"}, {"type": "null"}], "description": "Robot set code (unique among active sets)", "title": "Code"}, "description": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "description": "Robot set description (unique among active sets)", "title": "Description"}, "status": {"anyOf": [{"enum": ["REQUESTED", "IN_PRODUCTION", "IN_USE", "RETIRED"], "type": "string"}, {"type": "null"}], "description": "Lifecycle: REQUESTED | IN_PRODUCTION | IN_USE | RETIRED", "title": "Status"}, "service_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "List of service IDs to associate with the robot set", "title": "Service Ids"}}, "title": "RobotSetUpdate", "type": "object"}, "RobotSetServicesResponse": {"additionalProperties": false, "description": "Schema for RobotSetServices response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "RobotSetServices ID", "title": "Id", "type": "integer"}, "robot_set_id": {"description": "Robot set ID", "title": "Robot Set Id", "type": "integer"}, "service_id": {"description": "Service ID", "title": "Service Id", "type": "integer"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code", "title": "Service Code"}}, "required": ["updated_at", "id", "robot_set_id", "service_id", "service_code"], "title": "RobotSetServicesResponse", "type": "object"}, "ResourceSummary": {"additionalProperties": false, "description": "Summary of dispatch resources.", "properties": {"total": {"description": "Total number of resources", "title": "Total", "type": "integer"}, "technicians": {"description": "Number of technician resources", "title": "Technicians", "type": "integer"}, "teams": {"description": "Number of resource teams", "title": "Teams", "type": "integer"}}, "required": ["total", "technicians", "teams"], "title": "ResourceSummary", "type": "object"}, "PositionObject": {"additionalProperties": false, "description": "Nested Position object (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "is_lead": {"title": "Is Lead", "type": "boolean"}}, "required": ["id", "name", "is_lead"], "title": "PositionObject", "type": "object"}, "ResourceServicePositionResponse": {"additionalProperties": false, "description": "Schema for ResourceServicePosition response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "ResourceServicePosition ID", "title": "Id", "type": "integer"}, "resource_id": {"description": "Resource ID", "title": "Resource Id", "type": "integer"}, "service_id": {"description": "Service ID", "title": "Service Id", "type": "integer"}, "position": {"$ref": "#/components/schemas/PositionObject", "description": "Position"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Effective from date", "title": "From Date"}}, "required": ["updated_at", "id", "resource_id", "service_id", "position", "from_date"], "title": "ResourceServicePositionResponse", "type": "object"}, "ResourceServicePositionCreate": {"additionalProperties": false, "description": "Schema for creating a ResourceServicePosition.", "properties": {"service_id": {"description": "Service ID", "title": "Service Id", "type": "integer"}, "position_id": {"description": "Position ID", "title": "Position Id", "type": "integer"}, "from_date": {"description": "Effective from date (YYYY-MM-DD)", "title": "From Date", "type": "string"}}, "required": ["service_id", "position_id", "from_date"], "title": "ResourceServicePositionCreate", "type": "object"}, "ResourceServicePositionUpdate": {"additionalProperties": false, "description": "Schema for updating a ResourceServicePosition.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "position_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Position ID", "title": "Position Id"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Effective from date (YYYY-MM-DD)", "title": "From Date"}}, "title": "ResourceServicePositionUpdate", "type": "object"}, "CertificateObject": {"additionalProperties": false, "description": "Nested certificate object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "CertificateObject", "type": "object"}, "ResourceCertificateResponse": {"additionalProperties": false, "description": "Schema for ResourceCertificate response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "ResourceCertificate ID", "title": "Id", "type": "integer"}, "resource_id": {"description": "Resource ID", "title": "Resource Id", "type": "integer"}, "certificate": {"$ref": "#/components/schemas/CertificateObject", "description": "Certificate information"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Issuer FK", "title": "Issuer Id"}, "certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External certificate number", "title": "Certificate Number"}, "issued_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Issue date", "title": "Issued Date"}, "expiry_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Expiry date", "title": "Expiry Date"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional info", "title": "Additional Info"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External system this row was ingested from", "title": "Source"}, "source_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Identifier of the source row in the origin system", "title": "Source Id"}}, "required": ["updated_at", "id", "resource_id", "certificate"], "title": "ResourceCertificateResponse", "type": "object"}, "ResourceCertificateCreate": {"additionalProperties": false, "description": "Schema for creating a ResourceCertificate under a resource.", "properties": {"certificate_id": {"description": "Certificate ID", "title": "Certificate Id", "type": "integer"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Issuer FK", "title": "Issuer Id"}, "certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External certificate number", "title": "Certificate Number"}, "issued_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Issue date (YYYY-MM-DD)", "title": "Issued Date"}, "expiry_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Expiry date (YYYY-MM-DD)", "title": "Expiry Date"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional info", "title": "Additional Info"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External system this row was ingested from (e.g. \"bamboohr\")", "title": "Source"}, "source_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Identifier of the source row in the origin system", "title": "Source Id"}}, "required": ["certificate_id"], "title": "ResourceCertificateCreate", "type": "object"}, "ResourceCertificateUpdate": {"additionalProperties": false, "description": "Schema for updating a ResourceCertificate (partial).\n\n``certificate_id`` is intentionally omitted: the certificate a row points at\nis immutable. To assign a different certificate, delete this row and create a\nnew one.", "properties": {"issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Issuer FK", "title": "Issuer Id"}, "certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External certificate number", "title": "Certificate Number"}, "issued_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Issue date (YYYY-MM-DD)", "title": "Issued Date"}, "expiry_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Expiry date (YYYY-MM-DD)", "title": "Expiry Date"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional info", "title": "Additional Info"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External system this row was ingested from (e.g. \"bamboohr\")", "title": "Source"}, "source_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Identifier of the source row in the origin system", "title": "Source Id"}}, "title": "ResourceCertificateUpdate", "type": "object"}, "ResourceQueryParams": {"additionalProperties": false, "description": "Query parameters for resources endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by full_name, user name or email (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by resource type", "title": "Resource Type"}, "user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by linked user ID", "title": "User Id"}}, "title": "ResourceQueryParams", "type": "object"}, "ResourceCertificateOutput": {"additionalProperties": false, "description": "Output schema for a resource's certificate (embedded in ResourceResponse).\n\nExposes every non-audit ResourceCertificate field. ``certificate_id`` /\n``certificate_name`` / ``expiry_date`` are retained for backward\ncompatibility; the remaining fields mirror the standalone\n``/resources/{id}/certificates`` endpoint (``ResourceCertificateResponse``).", "properties": {"id": {"description": "ResourceCertificate row ID", "title": "Id", "type": "integer"}, "certificate_id": {"description": "Certificate ID", "title": "Certificate Id", "type": "integer"}, "certificate_name": {"description": "Certificate name", "title": "Certificate Name", "type": "string"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Issuer FK", "title": "Issuer Id"}, "certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External certificate number", "title": "Certificate Number"}, "issued_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Issue date (YYYY-MM-DD)", "title": "Issued Date"}, "expiry_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Expiry date (YYYY-MM-DD)", "title": "Expiry Date"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional info", "title": "Additional Info"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External system this row was ingested from", "title": "Source"}, "source_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Identifier of the source row in the origin system", "title": "Source Id"}}, "required": ["id", "certificate_id", "certificate_name"], "title": "ResourceCertificateOutput", "type": "object"}, "ResourceResponse": {"additionalProperties": false, "description": "Schema for Resource response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Resource ID", "title": "Id", "type": "integer"}, "full_name": {"description": "Resource full name", "title": "Full Name", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "employment_contract": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Employment contract details", "title": "Employment Contract"}, "qualifications": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "description": "Qualifications as JSON list", "title": "Qualifications"}, "user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "User ID", "title": "User Id"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID", "title": "Robot Set Id"}, "bamboohr_employee_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "BambooHR employee ID", "title": "Bamboohr Employee Id"}, "talentlms_user_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "TalentLMS user ID", "title": "Talentlms User Id"}, "certificates": {"description": "Certificates assigned to this resource", "items": {"$ref": "#/components/schemas/ResourceCertificateOutput"}, "title": "Certificates", "type": "array"}}, "required": ["updated_at", "id", "full_name"], "title": "ResourceResponse", "type": "object"}, "ResourceCertificateInput": {"additionalProperties": false, "description": "Input schema for a resource's certificate (used in Resource create/update).\n\nMirrors the writable non-audit fields of ResourceCertificate so the write\nsurface matches the enriched ``ResourceCertificateOutput`` read surface.\n\nSemantics are upsert (never replace-all): supply ``id`` to update that\nexisting issuance row, or omit ``id`` (and supply ``certificate_id``) to\nadd a new issuance. Rows not listed are left untouched; delete a row via\nDELETE /resources/{id}/certificates/{id}.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing ResourceCertificate row id to update; omit to add a new issuance.", "title": "Id"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Certificate ID (required when adding a new issuance)", "title": "Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Issuer FK", "title": "Issuer Id"}, "certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External certificate number", "title": "Certificate Number"}, "issued_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Issue date (YYYY-MM-DD)", "title": "Issued Date"}, "expiry_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Expiry date (YYYY-MM-DD)", "title": "Expiry Date"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional info", "title": "Additional Info"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External system this row was ingested from (e.g. \"bamboohr\")", "title": "Source"}, "source_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Identifier of the source row in the origin system", "title": "Source Id"}}, "title": "ResourceCertificateInput", "type": "object"}, "ResourceCreate": {"additionalProperties": false, "description": "Schema for creating a Resource.\n\nEither robot_set_id or user_id must be provided (but not both).\nThe full_name and email fields are auto-populated from the referenced entity;\nthey can be provided but will be overwritten. resource_type is only defaulted\nwhen omitted, so an explicit user-backed type (OFFICE) is honoured.", "properties": {"qualifications": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "description": "Qualifications as JSON list", "title": "Qualifications"}, "employment_contract": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Employment contract details", "title": "Employment Contract"}, "user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "User ID (for technicians and office staff)", "title": "User Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID (for robots)", "title": "Robot Set Id"}, "certificates": {"anyOf": [{"items": {"$ref": "#/components/schemas/ResourceCertificateInput"}, "type": "array"}, {"type": "null"}], "description": "Certificates to assign to this resource", "title": "Certificates"}, "bamboohr_employee_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External BambooHR employee ID to link on creation", "title": "Bamboohr Employee Id"}, "talentlms_user_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External TalentLMS user ID to link on creation", "title": "Talentlms User Id"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Auto-populated from user/robot_set", "title": "Full Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Auto-populated from user", "title": "Email"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Defaults to ROBOT for robot_set_id and TECHNICIAN for user_id. Supply OFFICE explicitly (with user_id) for office staff.", "title": "Resource Type"}}, "title": "ResourceCreate", "type": "object"}, "ResourceUpdate": {"additionalProperties": false, "description": "Schema for updating a Resource.\n\nEmployment contract, qualifications, certificates, and the BambooHR /\nTalentLMS links can be updated. `bamboohr_employee_id` and\n`talentlms_user_id` are three-state: omit the key to leave the link\nuntouched, pass `null` to unlink, or pass a string to create/replace\nthe link.", "properties": {"employment_contract": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Employment contract details", "title": "Employment Contract"}, "qualifications": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "description": "Qualifications as JSON list", "title": "Qualifications"}, "certificates": {"anyOf": [{"items": {"$ref": "#/components/schemas/ResourceCertificateInput"}, "type": "array"}, {"type": "null"}], "description": "Certificates to assign to this resource", "title": "Certificates"}, "bamboohr_employee_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External BambooHR employee ID to link. Pass null to unlink. Omit the key entirely to leave the existing link untouched.", "title": "Bamboohr Employee Id"}, "talentlms_user_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "External TalentLMS user ID to link. Pass null to unlink. Omit the key entirely to leave the existing link untouched.", "title": "Talentlms User Id"}}, "title": "ResourceUpdate", "type": "object"}, "ResourceSetQueryParams": {"additionalProperties": false, "description": "Query parameters for resource sets endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "ResourceSetQueryParams", "type": "object"}, "ResourceSetItemOutput": {"additionalProperties": false, "description": "Output schema for resource set item in responses (no timestamps).", "properties": {"id": {"description": "ResourceSetItem ID", "title": "Id", "type": "integer"}, "resource_id": {"description": "Resource ID", "title": "Resource Id", "type": "integer"}, "resource_type": {"description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is lead resource", "title": "Is Lead"}, "is_active": {"description": "Is active", "title": "Is Active", "type": "boolean"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}, "resource_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Resource Full Name"}}, "required": ["id", "resource_id", "resource_type", "is_active"], "title": "ResourceSetItemOutput", "type": "object"}, "ResourceSetResponse": {"additionalProperties": false, "description": "Schema for ResourceSet response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Resource set ID", "title": "Id", "type": "integer"}, "name": {"description": "Resource set name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource set description", "title": "Description"}, "set_items": {"description": "Resource set items", "items": {"$ref": "#/components/schemas/ResourceSetItemOutput"}, "title": "Set Items", "type": "array"}}, "required": ["updated_at", "id", "name"], "title": "ResourceSetResponse", "type": "object"}, "ResourceSetCreate": {"additionalProperties": false, "description": "Schema for creating a ResourceSet.", "properties": {"name": {"description": "Entity name", "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource set description", "title": "Description"}, "set_items": {"anyOf": [{"items": {"$ref": "#/components/schemas/ResourceSetItemInput"}, "type": "array"}, {"type": "null"}], "description": "Resource set items to create with the set", "title": "Set Items"}}, "required": ["name"], "title": "ResourceSetCreate", "type": "object"}, "ResourceSetItemInput": {"additionalProperties": false, "description": "Input schema for a resource set item (technician or robot from core.Resource).", "properties": {"resource_id": {"description": "Resource ID from core.Resource", "title": "Resource Id", "type": "integer"}, "resource_type": {"description": "Resource type: ROBOT or TECHNICIAN", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead (sets is_lead in ProjectResourceSetItem)", "title": "Is Lead"}}, "required": ["resource_id", "resource_type"], "title": "ResourceSetItemInput", "type": "object"}, "ResourceSetUpdate": {"additionalProperties": false, "description": "Schema for updating a ResourceSet.", "properties": {"name": {"description": "Entity name", "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource set description", "title": "Description"}, "set_items": {"anyOf": [{"items": {"$ref": "#/components/schemas/ResourceSetItemInput"}, "type": "array"}, {"type": "null"}], "description": "Resource set items (None=unchanged, []=clear all, [...]= replace)", "title": "Set Items"}}, "title": "ResourceSetUpdate", "type": "object"}, "CountryQueryParams": {"additionalProperties": false, "description": "Query parameters for countries endpoint (no pagination - returns all results).", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "CountryQueryParams", "type": "object"}, "CountryResponse": {"additionalProperties": false, "description": "Schema for Country response matching legacy /countries endpoint.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Country ID", "title": "Id", "type": "integer"}, "code": {"description": "ISO 3166-1 alpha-2 country code", "title": "Code", "type": "string"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Country name", "title": "Name"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Geographic region name", "title": "Region"}, "business_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Business region name", "title": "Business Region"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency code", "title": "Currency"}, "enabled": {"description": "Whether country is enabled", "title": "Enabled", "type": "boolean"}, "netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID", "title": "Netsuite Id"}}, "required": ["updated_at", "id", "code", "enabled"], "title": "CountryResponse", "type": "object"}, "ResolveCoordinatesResponse": {"additionalProperties": false, "description": "Resolved geographic data from coordinates.", "properties": {"latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude", "title": "Longitude"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Matched Timezone ID", "title": "Timezone Id"}, "timezone_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IANA timezone name (e.g. Europe/Berlin)", "title": "Timezone Name"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Matched Country ID", "title": "Country Id"}, "country_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 3166-1 alpha-2 code", "title": "Country Code"}, "address_line1": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Street address line resolved from coordinates", "title": "Address Line1"}, "city": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Nearest city name", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}}, "title": "ResolveCoordinatesResponse", "type": "object"}, "ResolveCoordinatesRequest": {"additionalProperties": false, "description": "Request body for resolving geographic data from coordinates.", "properties": {"latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate", "title": "Longitude"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text coordinates (e.g. 37\u00b051'05.0\"N 99\u00b012'53.5\"W)", "title": "Coordinates"}}, "title": "ResolveCoordinatesRequest", "type": "object"}, "LocationQueryParams": {"additionalProperties": false, "description": "Query parameters for locations endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Filter by location type"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by timezone ID", "title": "Timezone Id"}}, "title": "LocationQueryParams", "type": "object"}, "LocationType": {"description": "Allowed location type values in location.", "enum": ["WIND_PARK", "WAREHOUSE", "SERVICE_HUB", "PORT", "TRAINING_CENTER", "FACTORY", "OFFICE"], "title": "LocationType", "type": "string"}, "CountryObject": {"additionalProperties": false, "description": "Nested country object for responses (no timestamps in nested objects).", "properties": {"id": {"description": "Country ID", "title": "Id", "type": "integer"}, "code": {"description": "Country code (ISO 3166-1 alpha-2)", "title": "Code", "type": "string"}, "name": {"description": "Country name", "title": "Name", "type": "string"}}, "required": ["id", "code", "name"], "title": "CountryObject", "type": "object"}, "CurrencyIdCodeObject": {"additionalProperties": false, "description": "Nested currency object with only id and code (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "CurrencyIdCodeObject", "type": "object"}, "CustomerObject": {"additionalProperties": false, "description": "Nested customer object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "display_name": {"title": "Display Name", "type": "string"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "currency": {"anyOf": [{"$ref": "#/components/schemas/CurrencyIdCodeObject"}, {"type": "null"}], "description": "Customer currency (id and code only)"}}, "required": ["id", "display_name"], "title": "CustomerObject", "type": "object"}, "LocationCertificateOutput": {"additionalProperties": false, "description": "Output schema for location certificate in responses.", "properties": {"certificate_id": {"description": "Certificate ID", "title": "Certificate Id", "type": "integer"}, "certificate_name": {"description": "Certificate name", "title": "Certificate Name", "type": "string"}, "is_mandatory": {"description": "Whether certificate is mandatory", "title": "Is Mandatory", "type": "boolean"}}, "required": ["certificate_id", "certificate_name", "is_mandatory"], "title": "LocationCertificateOutput", "type": "object"}, "LocationResponse": {"additionalProperties": false, "description": "Schema for Location response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Location ID", "title": "Id", "type": "integer"}, "name": {"description": "Location name", "title": "Name", "type": "string"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Location type"}, "windpark_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Wind park type", "title": "Windpark Type"}, "address_line1": {"description": "Address line 1", "title": "Address Line1", "type": "string"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "City", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}], "description": "Country information"}, "timezone": {"anyOf": [{"$ref": "#/components/schemas/TimezoneObject"}, {"type": "null"}], "description": "Timezone information"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate", "title": "Longitude"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Coordinates string", "title": "Coordinates"}, "global_wind_park_db_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Global wind park database ID", "title": "Global Wind Park Db Id"}, "certificates": {"description": "Required certificates for the location", "items": {"$ref": "#/components/schemas/LocationCertificateOutput"}, "title": "Certificates", "type": "array"}, "customers": {"description": "Customers linked to the location", "items": {"$ref": "#/components/schemas/CustomerObject"}, "title": "Customers", "type": "array"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Site-specific attributes as JSON. Canonical keys: terrain_type, terrain_details, ground_conditions, regulations, operational_limitations", "title": "Custom Fields"}}, "required": ["updated_at", "id", "name", "address_line1"], "title": "LocationResponse", "type": "object"}, "TimezoneObject": {"additionalProperties": false, "description": "Nested timezone object for responses (no timestamps in nested objects).", "properties": {"id": {"description": "Timezone ID", "title": "Id", "type": "integer"}, "timezone": {"description": "Timezone name (e.g., Europe/Riga)", "title": "Timezone", "type": "string"}, "city": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "City name", "title": "City"}, "utc_offset": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "UTC offset (e.g., +02:00)", "title": "Utc Offset"}}, "required": ["id", "timezone"], "title": "TimezoneObject", "type": "object"}, "LocationCertificateInput": {"additionalProperties": false, "description": "Input schema for location certificate in create/update requests.", "properties": {"certificate_id": {"description": "Certificate ID", "title": "Certificate Id", "type": "integer"}, "is_mandatory": {"default": false, "description": "Whether certificate is mandatory", "title": "Is Mandatory", "type": "boolean"}}, "required": ["certificate_id"], "title": "LocationCertificateInput", "type": "object"}, "LocationCreate": {"additionalProperties": false, "description": "Schema for creating a Location.", "properties": {"name": {"description": "Location name", "minLength": 1, "title": "Name", "type": "string"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"$ref": "#/components/schemas/LocationType", "description": "Location type"}, "windpark_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Wind park type", "title": "Windpark Type"}, "address_line1": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address line 1 (auto-filled from coordinates text if omitted)", "title": "Address Line1"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "City (auto-filled from coordinates text if omitted)", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID (auto-filled from coordinates text if omitted)", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID (auto-filled from coordinates text if omitted)", "title": "Timezone Id"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate (auto-filled from coordinates text if omitted)", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate (auto-filled from coordinates text if omitted)", "title": "Longitude"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text coordinates (e.g. 37\u00b051'05.0\"N 99\u00b012'53.5\"W)", "title": "Coordinates"}, "global_wind_park_db_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Global wind park database ID", "title": "Global Wind Park Db Id"}, "certificates": {"anyOf": [{"items": {"$ref": "#/components/schemas/LocationCertificateInput"}, "type": "array"}, {"type": "null"}], "description": "Required certificates for the location", "title": "Certificates"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Site-specific attributes as JSON. Canonical keys: terrain_type, terrain_details, ground_conditions, regulations, operational_limitations", "example": {"ground_conditions": "sandy seabed", "operational_limitations": "No crane ops above 12 m/s wind", "regulations": "IMO / MCA compliant", "terrain_details": "North Sea, shallow waters", "terrain_type": "offshore"}, "title": "Custom Fields"}}, "required": ["name", "type"], "title": "LocationCreate", "type": "object"}, "LocationUpdate": {"additionalProperties": false, "description": "Schema for updating a Location.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Location name", "title": "Name"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Location type"}, "windpark_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Wind park type", "title": "Windpark Type"}, "address_line1": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address line 1", "title": "Address Line1"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "City", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID", "title": "Timezone Id"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate", "title": "Longitude"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text coordinates (e.g. 37\u00b051'05.0\"N 99\u00b012'53.5\"W)", "title": "Coordinates"}, "global_wind_park_db_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Global wind park database ID", "title": "Global Wind Park Db Id"}, "certificates": {"anyOf": [{"items": {"$ref": "#/components/schemas/LocationCertificateInput"}, "type": "array"}, {"type": "null"}], "description": "Required certificates for the location", "title": "Certificates"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Site-specific attributes as JSON. Canonical keys: terrain_type, terrain_details, ground_conditions, regulations, operational_limitations", "title": "Custom Fields"}}, "title": "LocationUpdate", "type": "object"}, "PricingUnitNestedResponse": {"additionalProperties": false, "description": "Nested response for pricing unit in service response (no timestamps in nested objects).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Netsuite Id"}}, "required": ["id", "name"], "title": "PricingUnitNestedResponse", "type": "object"}, "ServiceObject": {"additionalProperties": false, "description": "Nested service object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "is_service": {"description": "Whether this is a service (vs addon/material/support)", "title": "Is Service", "type": "boolean"}}, "required": ["id", "code", "is_service"], "title": "ServiceObject", "type": "object"}, "ServicePricingUnitResponse": {"additionalProperties": false, "description": "Schema for ServicePricingUnit response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "ServicePricingUnit ID", "title": "Id", "type": "integer"}, "is_default": {"description": "Whether this is the default pricing unit", "title": "Is Default", "type": "boolean"}, "service": {"$ref": "#/components/schemas/ServiceObject", "description": "Service information"}, "pricing_unit": {"$ref": "#/components/schemas/PricingUnitNestedResponse", "description": "Pricing unit information"}}, "required": ["updated_at", "id", "is_default", "service", "pricing_unit"], "title": "ServicePricingUnitResponse", "type": "object"}, "ServiceRelatedServiceResponse": {"additionalProperties": false, "description": "Schema for ServiceRelatedService response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "ServiceRelatedService ID", "title": "Id", "type": "integer"}, "service": {"$ref": "#/components/schemas/ServiceObject", "description": "Parent service information"}, "related_service": {"$ref": "#/components/schemas/ServiceObject", "description": "Related service information"}}, "required": ["updated_at", "id", "service", "related_service"], "title": "ServiceRelatedServiceResponse", "type": "object"}, "ServiceQueryParams": {"additionalProperties": false, "description": "Query parameters for services endpoint.\n\nNote: page and page_size are handled by the @paginate decorator from builderapi.utils.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "categories": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by category IDs (comma-separated, e.g., '1,2,3')", "title": "Categories"}, "is_service": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether this is a service (true/false)", "title": "Is Service"}, "service_family_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by capability family ID", "title": "Service Family Id"}, "deprecated": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by deprecation state (true/false). Omit to return both; pass false to list only the services that can still be sold.", "title": "Deprecated"}}, "title": "ServiceQueryParams", "type": "object"}, "ServiceCategoryNestedResponse": {"additionalProperties": false, "description": "Nested response for service category in service response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ServiceCategoryNestedResponse", "type": "object"}, "ServiceFamilyNestedResponse": {"additionalProperties": false, "description": "Nested response for service family in service response.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "code", "name"], "title": "ServiceFamilyNestedResponse", "type": "object"}, "ServiceGroupNestedResponse": {"additionalProperties": false, "description": "Nested response for service group in service response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ServiceGroupNestedResponse", "type": "object"}, "ServiceResponse": {"additionalProperties": false, "description": "Schema for Service response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Service ID", "title": "Id", "type": "integer"}, "code": {"description": "Service code", "title": "Code", "type": "string"}, "description": {"description": "Service description", "title": "Description", "type": "string"}, "is_rat": {"description": "Whether service is RAT", "title": "Is Rat", "type": "boolean"}, "is_service": {"description": "Whether this is a service", "title": "Is Service", "type": "boolean"}, "deprecated": {"description": "Whether the service is retired from the sellable catalogue. Clients should hide deprecated services from pickers; rows that already reference one stay valid and editable.", "title": "Deprecated", "type": "boolean"}, "category": {"anyOf": [{"$ref": "#/components/schemas/ServiceCategoryNestedResponse"}, {"type": "null"}], "description": "Service category"}, "service_group": {"anyOf": [{"$ref": "#/components/schemas/ServiceGroupNestedResponse"}, {"type": "null"}], "description": "Service group"}, "service_family": {"anyOf": [{"$ref": "#/components/schemas/ServiceFamilyNestedResponse"}, {"type": "null"}], "description": "Capability family that executes this service. Omitted entirely for catalogue rows that carry no capability (support, mobilisation, idle, direct materials) - responses exclude unset fields rather than sending null."}, "pricing_unit_types": {"description": "Available pricing unit types", "items": {"$ref": "#/components/schemas/PricingUnitNestedResponse"}, "title": "Pricing Unit Types", "type": "array"}, "component_types": {"description": "Component types applicable for this service", "items": {"$ref": "#/components/schemas/ComponentTypeObject"}, "title": "Component Types", "type": "array"}}, "required": ["updated_at", "id", "code", "description", "is_rat", "is_service", "deprecated"], "title": "ServiceResponse", "type": "object"}, "ServiceCategoryResponse": {"additionalProperties": false, "description": "Schema for ServiceCategory response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Service category ID", "title": "Id", "type": "integer"}, "code": {"description": "Service category code", "title": "Code", "type": "string"}, "name": {"description": "Service category name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "code", "name"], "title": "ServiceCategoryResponse", "type": "object"}, "ServiceFamilyQueryParams": {"additionalProperties": false, "description": "Query parameters for the service families endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code or name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by exact family code", "title": "Code"}}, "title": "ServiceFamilyQueryParams", "type": "object"}, "ServiceFamilyResponse": {"additionalProperties": false, "description": "Schema for ServiceFamily response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Service family ID", "title": "Id", "type": "integer"}, "code": {"description": "Service family code", "title": "Code", "type": "string"}, "name": {"description": "Service family name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "code", "name"], "title": "ServiceFamilyResponse", "type": "object"}, "ServiceGroupResponse": {"additionalProperties": false, "description": "Schema for ServiceGroup response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Service group ID", "title": "Id", "type": "integer"}, "name": {"description": "Service group name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "name"], "title": "ServiceGroupResponse", "type": "object"}, "PricingUnitResponse": {"additionalProperties": false, "description": "Schema for PricingUnit response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Pricing unit ID", "title": "Id", "type": "integer"}, "name": {"description": "Pricing unit name", "title": "Name", "type": "string"}, "netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID", "title": "Netsuite Id"}}, "required": ["updated_at", "id", "name"], "title": "PricingUnitResponse", "type": "object"}, "ErpPartQueryParams": {"additionalProperties": false, "description": "Query params for listing ERP parts.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "erp_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Erp Status"}, "part_code_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Part Code Id"}, "flagged": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Flagged"}}, "title": "ErpPartQueryParams", "type": "object"}, "ErpPartCategoryObject": {"additionalProperties": false, "description": "Nested item-category object for ERP part responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"title": "Description", "type": "string"}}, "required": ["id", "code", "description"], "title": "ErpPartCategoryObject", "type": "object"}, "ErpPartCodeObject": {"additionalProperties": false, "description": "Nested Monitor part-classification code (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"title": "Description", "type": "string"}}, "required": ["id", "code", "description"], "title": "ErpPartCodeObject", "type": "object"}, "ErpPartResponse": {"additionalProperties": false, "description": "Schema for a synced Monitor ERP part.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "ERP part ID (Ops Hub)", "title": "Id", "type": "integer"}, "erp_id": {"description": "Monitor ERP internal part id", "title": "Erp Id", "type": "integer"}, "part_number": {"description": "Monitor part number", "title": "Part Number", "type": "string"}, "description": {"default": "", "description": "Part description", "title": "Description", "type": "string"}, "erp_status": {"default": "", "description": "Raw Monitor status code", "title": "Erp Status", "type": "string"}, "unit": {"default": "", "description": "Standard unit code (pcs, kg, ...)", "title": "Unit", "type": "string"}, "part_code": {"anyOf": [{"$ref": "#/components/schemas/ErpPartCodeObject"}, {"type": "null"}], "description": "Monitor's own classification (e.g. 5007 PPE)"}, "category": {"anyOf": [{"$ref": "#/components/schemas/ErpPartCategoryObject"}, {"type": "null"}], "description": "Ops-Hub-assigned item category (PPE, Consumable, ...)"}}, "required": ["updated_at", "id", "erp_id", "part_number"], "title": "ErpPartResponse", "type": "object"}, "ErpPartUpdate": {"additionalProperties": false, "description": "Schema for flagging an ERP part \u2014 only the category is editable.", "properties": {"category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Item category to assign; null clears the flag", "title": "Category Id"}}, "title": "ErpPartUpdate", "type": "object"}, "ErpPartCodeResponse": {"additionalProperties": false, "description": "Schema for a synced Monitor part-classification code.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Part code ID (Ops Hub)", "title": "Id", "type": "integer"}, "code": {"description": "Monitor code, e.g. 5007", "title": "Code", "type": "string"}, "description": {"default": "", "description": "Monitor label, e.g. 'Equ. Personal Safety Equipmen (PPE)'", "title": "Description", "type": "string"}}, "required": ["updated_at", "id", "code"], "title": "ErpPartCodeResponse", "type": "object"}, "ItemCategoryResponse": {"additionalProperties": false, "description": "One row in the ``core.item_category`` lookup.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"title": "Description", "type": "string"}}, "required": ["id", "code", "description"], "title": "ItemCategoryResponse", "type": "object"}, "ServiceStandardItemQueryParams": {"additionalProperties": false, "description": "Query params for listing standard-set lines.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Region"}, "part_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Part Id"}}, "title": "ServiceStandardItemQueryParams", "type": "object"}, "ErpPartObject": {"additionalProperties": false, "description": "Nested ERP part object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "part_number": {"title": "Part Number", "type": "string"}, "description": {"default": "", "title": "Description", "type": "string"}, "unit": {"default": "", "title": "Unit", "type": "string"}, "category": {"anyOf": [{"$ref": "#/components/schemas/ErpPartCategoryObject"}, {"type": "null"}]}}, "required": ["id", "part_number"], "title": "ErpPartObject", "type": "object"}, "ServiceStandardItemResponse": {"additionalProperties": false, "description": "Schema for one standard-set line of a service.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Standard item ID", "title": "Id", "type": "integer"}, "region": {"description": "Region the line applies to (EU/NA)", "title": "Region", "type": "string"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceObject"}, {"type": "null"}], "description": "Service; null = applies to all services in the region"}, "part": {"$ref": "#/components/schemas/ErpPartObject", "description": "Monitor ERP part"}, "quantity": {"description": "Quantity per scope", "title": "Quantity", "type": "number"}, "unit": {"description": "Unit (pcs, pair, set, ...)", "title": "Unit", "type": "string"}, "scope": {"description": "PER_SET, PER_PERSON, PER_WTG or PER_BLADE", "title": "Scope", "type": "string"}}, "required": ["updated_at", "id", "region", "part", "quantity", "unit", "scope"], "title": "ServiceStandardItemResponse", "type": "object"}, "ServiceStandardItemCreate": {"additionalProperties": false, "description": "Schema for creating a standard-set line.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service; omit for a region-common line", "title": "Service Id"}, "region": {"default": "EU", "description": "Region", "enum": ["EU", "NA"], "title": "Region", "type": "string"}, "part_id": {"description": "ERP part ID (Ops Hub id)", "title": "Part Id", "type": "integer"}, "quantity": {"default": 1, "description": "Quantity per scope", "exclusiveMinimum": 0.0, "title": "Quantity", "type": "number"}, "unit": {"description": "Unit (pcs, pair, set, ...)", "minLength": 1, "title": "Unit", "type": "string"}, "scope": {"default": "PER_SET", "description": "Whether quantity is per set, per person, per wind turbine, or per blade", "enum": ["PER_SET", "PER_PERSON", "PER_WTG", "PER_BLADE"], "title": "Scope", "type": "string"}}, "required": ["part_id", "unit"], "title": "ServiceStandardItemCreate", "type": "object"}, "ServiceStandardItemUpdate": {"additionalProperties": false, "description": "Schema for updating a standard-set line.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service", "title": "Service Id"}, "region": {"anyOf": [{"enum": ["EU", "NA"], "type": "string"}, {"type": "null"}], "description": "Region", "title": "Region"}, "part_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ERP part ID", "title": "Part Id"}, "quantity": {"anyOf": [{"exclusiveMinimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "unit": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Unit", "title": "Unit"}, "scope": {"anyOf": [{"enum": ["PER_SET", "PER_PERSON", "PER_WTG", "PER_BLADE"], "type": "string"}, {"type": "null"}], "description": "Scope", "title": "Scope"}}, "title": "ServiceStandardItemUpdate", "type": "object"}, "CertificateRequirementRuleQueryParams": {"additionalProperties": false, "description": "Query params for listing certificate mapping rules.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Certificate Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "service_family_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Family Id"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Region"}}, "title": "CertificateRequirementRuleQueryParams", "type": "object"}, "CertificateRequirementRuleResponse": {"additionalProperties": false, "description": "One certificate mapping rule: (service | family | all) \u00d7 region \u00d7 customer \u2192 certificate.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Rule ID", "title": "Id", "type": "integer"}, "certificate": {"$ref": "#/components/schemas/CertificateObject", "description": "Required certificate"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/CustomerObject"}, {"type": "null"}], "description": "Customer the rule applies to; null = every customer"}, "location": {"anyOf": [{"$ref": "#/components/schemas/NestedIdName"}, {"type": "null"}], "description": "Site the rule applies to; null = every site"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceObject"}, {"type": "null"}], "description": "Exact service the rule applies to"}, "service_family": {"anyOf": [{"$ref": "#/components/schemas/ServiceFamilyObject"}, {"type": "null"}], "description": "Service family the rule applies to"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Region the rule applies to (EU/NA); null = every region", "title": "Region"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Condition shown next to the certificate on the pre-job form", "title": "Comment"}}, "required": ["updated_at", "id", "certificate"], "title": "CertificateRequirementRuleResponse", "type": "object"}, "NestedIdName": {"additionalProperties": false, "description": "Generic nested object with id and name (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "NestedIdName", "type": "object"}, "ServiceFamilyObject": {"additionalProperties": false, "description": "Nested service-family object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "code", "name"], "title": "ServiceFamilyObject", "type": "object"}, "CertificateRequirementRuleCreate": {"additionalProperties": false, "description": "Schema for creating a certificate mapping rule.", "properties": {"certificate_id": {"description": "Certificate ID", "title": "Certificate Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer; omit for every customer", "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Site; omit for every site", "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Exact service; mutually exclusive with service_family_id", "title": "Service Id"}, "service_family_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service family; mutually exclusive with service_id", "title": "Service Family Id"}, "region": {"anyOf": [{"enum": ["EU", "NA"], "type": "string"}, {"type": "null"}], "description": "Region; omit for every region", "title": "Region"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Condition note", "title": "Comment"}}, "required": ["certificate_id"], "title": "CertificateRequirementRuleCreate", "type": "object"}, "CertificateRequirementRuleUpdate": {"additionalProperties": false, "description": "Schema for updating a certificate mapping rule.", "properties": {"certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Certificate ID", "title": "Certificate Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer", "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Site", "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Exact service", "title": "Service Id"}, "service_family_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service family", "title": "Service Family Id"}, "region": {"anyOf": [{"enum": ["EU", "NA"], "type": "string"}, {"type": "null"}], "description": "Region", "title": "Region"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Condition note", "title": "Comment"}}, "title": "CertificateRequirementRuleUpdate", "type": "object"}, "CertificateRequirementGroupSave": {"additionalProperties": false, "description": "Bulk save of one mapping group in a single transaction.\n\nTargets are (certificate \u00d7 unit) pairs sharing region/customer/comment.\nRules in ``existing_rule_ids`` not matching a target are soft-deleted;\nmatching ones are patched when the shared fields changed; the rest are\ncreated.", "properties": {"certificate_ids": {"description": "Certificates", "items": {"type": "integer"}, "minItems": 1, "title": "Certificate Ids", "type": "array"}, "units": {"description": "Scopes the certificates apply to", "items": {"$ref": "#/components/schemas/CertificateRequirementScopeUnit"}, "minItems": 1, "title": "Units", "type": "array"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer; omit for every customer", "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Site; omit for every site", "title": "Location Id"}, "region": {"anyOf": [{"enum": ["EU", "NA"], "type": "string"}, {"type": "null"}], "description": "Region; omit for every region", "title": "Region"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Condition note", "title": "Comment"}, "existing_rule_ids": {"description": "Rules currently forming the edited group; empty on create", "items": {"type": "integer"}, "title": "Existing Rule Ids", "type": "array"}}, "required": ["certificate_ids", "units"], "title": "CertificateRequirementGroupSave", "type": "object"}, "CertificateRequirementScopeUnit": {"additionalProperties": false, "description": "One scope of a mapping group: a service, a family, or (both empty) all services.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Exact service", "title": "Service Id"}, "service_family_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service family", "title": "Service Family Id"}}, "title": "CertificateRequirementScopeUnit", "type": "object"}, "RelationshipTypeResponse": {"additionalProperties": false, "description": "Schema for RelationshipType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Relationship type ID", "title": "Id", "type": "integer"}, "code": {"description": "Relationship type code", "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}}, "required": ["updated_at", "id", "code"], "title": "RelationshipTypeResponse", "type": "object"}, "StandardQueryParams": {"additionalProperties": false, "description": "Query parameters for standards endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field", "title": "Sort"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by type", "title": "Type"}, "key": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by key", "title": "Key"}}, "title": "StandardQueryParams", "type": "object"}, "StandardResponse": {"additionalProperties": false, "description": "Schema for Standard response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Standard ID", "title": "Id", "type": "integer"}, "name": {"description": "Standard name", "title": "Name", "type": "string"}, "type": {"description": "Standard type", "title": "Type", "type": "string"}, "key": {"description": "Standard key type", "title": "Key", "type": "string"}}, "required": ["updated_at", "id", "name", "type", "key"], "title": "StandardResponse", "type": "object"}, "PositionQueryParams": {"additionalProperties": false, "description": "Query parameters for positions endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by lead flag", "title": "Is Lead"}}, "title": "PositionQueryParams", "type": "object"}, "PositionResponse": {"additionalProperties": false, "description": "Schema for Position response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Position ID", "title": "Id", "type": "integer"}, "name": {"description": "Position name", "title": "Name", "type": "string"}, "is_lead": {"description": "Whether this position is a lead role", "title": "Is Lead", "type": "boolean"}}, "required": ["updated_at", "id", "name", "is_lead"], "title": "PositionResponse", "type": "object"}, "PositionCreate": {"additionalProperties": false, "description": "Schema for creating a Position.", "properties": {"name": {"description": "Position name", "minLength": 1, "title": "Name", "type": "string"}, "is_lead": {"default": false, "description": "Whether this position is a lead role", "title": "Is Lead", "type": "boolean"}}, "required": ["name"], "title": "PositionCreate", "type": "object"}, "PositionUpdate": {"additionalProperties": false, "description": "Schema for updating a Position.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Position name", "title": "Name"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether this position is a lead role", "title": "Is Lead"}}, "title": "PositionUpdate", "type": "object"}, "UserQueryParams": {"additionalProperties": false, "description": "Query parameters for user list endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by first name, last name, or email (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by first_name, last_name, or email (prefix with - for descending)", "title": "Sort"}, "roles": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by role names (comma-separated)", "title": "Roles"}}, "title": "UserQueryParams", "type": "object"}, "UserCustomerObject": {"additionalProperties": false, "description": "Nested customer reference for user responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "display_name": {"title": "Display Name", "type": "string"}}, "required": ["id", "display_name"], "title": "UserCustomerObject", "type": "object"}, "UserResponse": {"additionalProperties": false, "description": "Schema for user list response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "User ID", "title": "Id", "type": "integer"}, "first_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User first name", "title": "First Name"}, "last_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User last name", "title": "Last Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User email", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User phone number", "title": "Phone"}, "roles": {"description": "Role names", "items": {"type": "string"}, "title": "Roles", "type": "array"}, "customers": {"description": "Assigned customers", "items": {"$ref": "#/components/schemas/UserCustomerObject"}, "title": "Customers", "type": "array"}}, "required": ["updated_at", "id"], "title": "UserResponse", "type": "object"}, "UserCreate": {"additionalProperties": false, "description": "Schema for creating a user.", "properties": {"first_name": {"description": "User first name", "title": "First Name", "type": "string"}, "last_name": {"description": "User last name", "title": "Last Name", "type": "string"}, "email": {"description": "User email (used as username)", "format": "email", "title": "Email", "type": "string"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User phone number", "title": "Phone"}, "group_ids": {"description": "List of group/role IDs to assign", "items": {"type": "integer"}, "title": "Group Ids", "type": "array"}, "customer_ids": {"description": "List of customer IDs to link", "items": {"type": "integer"}, "title": "Customer Ids", "type": "array"}}, "required": ["first_name", "last_name", "email"], "title": "UserCreate", "type": "object"}, "UserUpdate": {"additionalProperties": false, "description": "Schema for updating a user.", "properties": {"first_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User first name", "title": "First Name"}, "last_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User last name", "title": "Last Name"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User phone number", "title": "Phone"}, "group_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "List of group/role IDs to assign", "title": "Group Ids"}, "customer_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "List of customer IDs to link", "title": "Customer Ids"}}, "title": "UserUpdate", "type": "object"}, "IDWithName": {"additionalProperties": false, "description": "Schema for ID with name.", "properties": {"id": {"description": "Identifier.", "title": "Id", "type": "integer"}, "name": {"description": "Name.", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "IDWithName", "type": "object"}, "CustomerQueryParams": {"additionalProperties": false, "description": "Query parameters for customers endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by display_name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by currency ID", "title": "Currency Id"}, "type": {"allOf": [{"description": "Which customer types a list returns.\n\nEvery :class:`CustomerType` plus ``ALL``. Kept separate from\n:class:`CustomerType` because ``ALL`` is a question a caller can ask, never a\nvalue a customer row can hold.\n\n``COMMERCIAL`` is the default on every list, so a customer that cannot be\nbilled never reaches a picker asking \"which commercial party is this\". ``ALL``\nis for the surfaces that administer the ``parent_customer`` hierarchy rather\nthan choose a payer.", "enum": ["COMMERCIAL", "VIRTUAL", "ALL"], "title": "CustomerTypeFilter", "type": "string"}], "default": "COMMERCIAL", "description": "Which customer types to return. Defaults to COMMERCIAL, so no picker offers a customer that cannot be billed. ALL returns every type, for the surfaces that administer the parent-customer hierarchy rather than choose a payer."}, "parent_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent customer ID", "title": "Parent Customer Id"}, "pipedrive_org_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by Pipedrive organization ID", "title": "Pipedrive Org Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter to customers linked to this Location via the core.customer_locations junction (active rows only).", "title": "Location Id"}}, "title": "CustomerQueryParams", "type": "object"}, "CustomerTypeFilter": {"description": "Which customer types a list returns.\n\nEvery :class:`CustomerType` plus ``ALL``. Kept separate from\n:class:`CustomerType` because ``ALL`` is a question a caller can ask, never a\nvalue a customer row can hold.\n\n``COMMERCIAL`` is the default on every list, so a customer that cannot be\nbilled never reaches a picker asking \"which commercial party is this\". ``ALL``\nis for the surfaces that administer the ``parent_customer`` hierarchy rather\nthan choose a payer.", "enum": ["COMMERCIAL", "VIRTUAL", "ALL"], "title": "CustomerTypeFilter", "type": "string"}, "CurrencyObject": {"additionalProperties": false, "description": "Nested currency object for responses (no timestamps in nested objects).", "properties": {"id": {"description": "Currency ID", "title": "Id", "type": "integer"}, "code": {"description": "Currency code (ISO 4217)", "title": "Code", "type": "string"}, "name": {"description": "Currency name", "title": "Name", "type": "string"}}, "required": ["id", "code", "name"], "title": "CurrencyObject", "type": "object"}, "CustomerResponse": {"additionalProperties": false, "description": "Schema for Customer response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Customer ID", "title": "Id", "type": "integer"}, "number": {"description": "Customer number", "title": "Number", "type": "string"}, "display_name": {"description": "Display name", "title": "Display Name", "type": "string"}, "legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legal name", "title": "Legal Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}], "description": "Country information"}, "parent_customer": {"anyOf": [{"$ref": "#/components/schemas/ParentCustomerObject"}, {"type": "null"}], "description": "Parent customer information"}, "type": {"allOf": [{"$ref": "#/components/schemas/CustomerType"}], "default": "COMMERCIAL", "description": "What kind of party this customer is"}, "currency": {"anyOf": [{"$ref": "#/components/schemas/CurrencyObject"}, {"type": "null"}], "description": "Currency information"}, "vat_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT number", "title": "Vat Number"}, "registration_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration number", "title": "Registration Number"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "netsuite_subsidiary_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite subsidiary (Aerones billing entity) internal ID", "title": "Netsuite Subsidiary Id"}, "pipedrive_org_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pipedrive organization ID", "title": "Pipedrive Org Id"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Custom fields as JSON", "title": "Custom Fields"}, "logo_file_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Logo file storage id (fileupload.Files)", "title": "Logo File Id"}}, "required": ["updated_at", "id", "number", "display_name"], "title": "CustomerResponse", "type": "object"}, "CustomerType": {"description": "What kind of party a customer row represents.\n\n``COMMERCIAL`` is an ordinary customer: billable, mirrored to NetSuite, and the\nanswer every customer picker in the product is asking for.\n\n``VIRTUAL`` is an organisation that exists only so a group of users can read\nacross the customers beneath it in the ``parent_customer`` tree. It is never\nbilled and never mirrored to NetSuite or Pipedrive.\n\nThe vocabulary lives here rather than in a database constraint, so adding a kind\nstays a product decision and not a deploy-ordering problem.\n\nA type carries no access meaning. Scope expansion is decided entirely by\n``parent_customer`` and ``deleted_at`` in ``rls.tenant_scope``, which never reads\nthis column, so changing it neither grants nor revokes anything.", "enum": ["COMMERCIAL", "VIRTUAL"], "title": "CustomerType", "type": "string"}, "ParentCustomerObject": {"additionalProperties": false, "description": "Nested parent customer object for responses (no timestamps in nested objects).", "properties": {"id": {"description": "Parent customer ID", "title": "Id", "type": "integer"}, "display_name": {"description": "Parent customer display name", "title": "Display Name", "type": "string"}}, "required": ["id", "display_name"], "title": "ParentCustomerObject", "type": "object"}, "CustomerCreate": {"additionalProperties": false, "description": "Schema for creating a Customer. Number is auto-generated.\n\n``country_id``, ``currency_id`` and ``netsuite_subsidiary_id`` are required of a\ncommercial customer and meaningless on a virtual one, so the per-kind contract is\nenforced by ``CustomerManager.create``, the one place every channel goes\nthrough, rather than by this schema.", "properties": {"display_name": {"description": "Display name", "minLength": 1, "title": "Display Name", "type": "string"}, "legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legal name", "title": "Legal Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID, required unless type is VIRTUAL", "title": "Country Id"}, "parent_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent customer ID", "title": "Parent Customer Id"}, "type": {"allOf": [{"$ref": "#/components/schemas/CustomerType"}], "default": "COMMERCIAL", "description": "What kind of party this is. A VIRTUAL customer exists only so a group of users can read across the customers beneath it: never billed, never mirrored to NetSuite, and hidden by default from the customer lists. It requires display_name only, and refuses the NetSuite and Pipedrive ids."}, "vat_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT number", "title": "Vat Number"}, "registration_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration number", "title": "Registration Number"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Currency ID, required unless type is VIRTUAL", "title": "Currency Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "netsuite_subsidiary_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite subsidiary (Aerones billing entity) internal ID, required unless type is VIRTUAL, and refused for a virtual customer. The customer is mirrored to NetSuite under this subsidiary, unless netsuite_customer_id is supplied (importing an already-linked customer), in which case no NetSuite record is created.", "title": "Netsuite Subsidiary Id"}, "pipedrive_org_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pipedrive organization ID", "title": "Pipedrive Org Id"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Custom fields as JSON", "title": "Custom Fields"}, "logo_file_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Logo file storage id (fileupload.Files; upload via POST /api/files)", "title": "Logo File Id"}}, "required": ["display_name"], "title": "CustomerCreate", "type": "object"}, "CustomerUpdate": {"additionalProperties": false, "description": "Schema for updating a Customer.", "properties": {"number": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Customer number", "title": "Number"}, "display_name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Display name", "title": "Display Name"}, "legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legal name", "title": "Legal Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "parent_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent customer ID", "title": "Parent Customer Id"}, "vat_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT number", "title": "Vat Number"}, "registration_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration number", "title": "Registration Number"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Currency ID", "title": "Currency Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "pipedrive_org_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pipedrive organization ID", "title": "Pipedrive Org Id"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Custom fields as JSON", "title": "Custom Fields"}, "logo_file_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Logo file storage id (fileupload.Files). Set to null to remove the logo.", "title": "Logo File Id"}}, "title": "CustomerUpdate", "type": "object"}, "CustomerNetsuiteSubsidiary": {"additionalProperties": false, "description": "Current NetSuite subsidiary for a customer (source of truth = NetSuite).", "properties": {"subsidiary_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Subsidiary Id"}}, "title": "CustomerNetsuiteSubsidiary", "type": "object"}, "VendorQueryParams": {"additionalProperties": false, "description": "Query parameters for vendors endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by display_name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by currency ID", "title": "Currency Id"}, "parent_vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent vendor ID", "title": "Parent Vendor Id"}}, "title": "VendorQueryParams", "type": "object"}, "ParentVendorObject": {"additionalProperties": false, "description": "Nested parent vendor object for responses (no timestamps in nested objects).", "properties": {"id": {"description": "Parent vendor ID", "title": "Id", "type": "integer"}, "display_name": {"description": "Parent vendor display name", "title": "Display Name", "type": "string"}}, "required": ["id", "display_name"], "title": "ParentVendorObject", "type": "object"}, "VendorResponse": {"additionalProperties": false, "description": "Schema for Vendor response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Vendor ID", "title": "Id", "type": "integer"}, "number": {"description": "Vendor number", "title": "Number", "type": "string"}, "display_name": {"description": "Display name", "title": "Display Name", "type": "string"}, "legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legal name", "title": "Legal Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}], "description": "Country information"}, "parent_vendor": {"anyOf": [{"$ref": "#/components/schemas/ParentVendorObject"}, {"type": "null"}], "description": "Parent vendor information"}, "currency": {"anyOf": [{"$ref": "#/components/schemas/CurrencyObject"}, {"type": "null"}], "description": "Currency information"}, "vat_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT number", "title": "Vat Number"}, "registration_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration number", "title": "Registration Number"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "netsuite_vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite vendor ID", "title": "Netsuite Vendor Id"}}, "required": ["updated_at", "id", "number", "display_name"], "title": "VendorResponse", "type": "object"}, "VendorCreate": {"additionalProperties": false, "description": "Schema for creating a Vendor. Number is auto-generated.", "properties": {"display_name": {"description": "Display name", "minLength": 1, "title": "Display Name", "type": "string"}, "legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legal name", "title": "Legal Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "parent_vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent vendor ID", "title": "Parent Vendor Id"}, "vat_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT number", "title": "Vat Number"}, "registration_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration number", "title": "Registration Number"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Currency ID", "title": "Currency Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "netsuite_vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite vendor ID", "title": "Netsuite Vendor Id"}}, "required": ["display_name"], "title": "VendorCreate", "type": "object"}, "VendorUpdate": {"additionalProperties": false, "description": "Schema for updating a Vendor.", "properties": {"number": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Vendor number", "title": "Number"}, "display_name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Display name", "title": "Display Name"}, "legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legal name", "title": "Legal Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "parent_vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent vendor ID", "title": "Parent Vendor Id"}, "vat_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "VAT number", "title": "Vat Number"}, "registration_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration number", "title": "Registration Number"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Currency ID", "title": "Currency Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "netsuite_vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite vendor ID", "title": "Netsuite Vendor Id"}}, "title": "VendorUpdate", "type": "object"}, "CustomerContactResponse": {"additionalProperties": false, "description": "Schema for CustomerContact response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Contact ID", "title": "Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer ID", "title": "Customer Id"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}, "name": {"description": "Contact name", "title": "Name", "type": "string"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Contact title", "title": "Title"}, "department": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Department", "title": "Department"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "is_primary": {"description": "Is primary contact", "title": "Is Primary", "type": "boolean"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}}, "required": ["updated_at", "id", "name", "is_primary"], "title": "CustomerContactResponse", "type": "object"}, "CustomerContactCreate": {"additionalProperties": false, "description": "Schema for creating a CustomerContact.", "properties": {"name": {"description": "Contact name", "minLength": 1, "title": "Name", "type": "string"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Contact title", "title": "Title"}, "department": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Department", "title": "Department"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "is_primary": {"default": false, "description": "Is primary contact", "title": "Is Primary", "type": "boolean"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}}, "required": ["name"], "title": "CustomerContactCreate", "type": "object"}, "CustomerContactUpdate": {"additionalProperties": false, "description": "Schema for updating a CustomerContact.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Contact name", "title": "Name"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Contact title", "title": "Title"}, "department": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Department", "title": "Department"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number", "title": "Phone"}, "is_primary": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is primary contact", "title": "Is Primary"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}}, "title": "CustomerContactUpdate", "type": "object"}, "CustomerAddressResponse": {"additionalProperties": false, "description": "Schema for CustomerAddress response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Address ID", "title": "Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer ID", "title": "Customer Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address name", "title": "Name"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address type", "title": "Type"}, "address_line1": {"description": "Address line 1", "title": "Address Line1", "type": "string"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "City", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}], "description": "Country information"}, "timezone": {"anyOf": [{"$ref": "#/components/schemas/TimezoneObject"}, {"type": "null"}], "description": "Timezone information"}}, "required": ["updated_at", "id", "address_line1"], "title": "CustomerAddressResponse", "type": "object"}, "CustomerAddressCreate": {"additionalProperties": false, "description": "Schema for creating a CustomerAddress.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address name", "title": "Name"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"anyOf": [{"$ref": "#/components/schemas/CustomerAddressType"}, {"type": "null"}], "description": "Address type"}, "address_line1": {"description": "Address line 1", "minLength": 1, "title": "Address Line1", "type": "string"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "City", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID", "title": "Timezone Id"}}, "required": ["address_line1"], "title": "CustomerAddressCreate", "type": "object"}, "CustomerAddressType": {"description": "Enum for customer address types.", "enum": ["PRIMARY", "BILLING", "LEGAL", "FACTUAL", "SHIPPING", "OM_BUILDING"], "title": "CustomerAddressType", "type": "string"}, "CustomerAddressUpdate": {"additionalProperties": false, "description": "Schema for updating a CustomerAddress.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address name", "title": "Name"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address type", "title": "Type"}, "address_line1": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address line 1", "title": "Address Line1"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "City", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID", "title": "Timezone Id"}}, "title": "CustomerAddressUpdate", "type": "object"}, "CustomerBankAccountResponse": {"additionalProperties": false, "description": "Schema for CustomerBankAccount response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Bank account ID", "title": "Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer ID", "title": "Customer Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bank account name", "title": "Name"}, "iban": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IBAN number", "title": "Iban"}, "account_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Account number", "title": "Account Number"}, "bank_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bank name", "title": "Bank Name"}, "swift_bic": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SWIFT/BIC code", "title": "Swift Bic"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency code (ISO 4217)", "title": "Currency Code"}, "is_primary": {"description": "Is primary bank account", "title": "Is Primary", "type": "boolean"}}, "required": ["updated_at", "id", "is_primary"], "title": "CustomerBankAccountResponse", "type": "object"}, "CustomerBankAccountCreate": {"additionalProperties": false, "description": "Schema for creating a CustomerBankAccount.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bank account name", "title": "Name"}, "iban": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IBAN number", "title": "Iban"}, "account_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Account number", "title": "Account Number"}, "bank_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bank name", "title": "Bank Name"}, "swift_bic": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SWIFT/BIC code", "title": "Swift Bic"}, "currency_code": {"anyOf": [{"maxLength": 3, "type": "string"}, {"type": "null"}], "description": "Currency code (ISO 4217)", "title": "Currency Code"}, "is_primary": {"default": false, "description": "Is primary bank account", "title": "Is Primary", "type": "boolean"}}, "title": "CustomerBankAccountCreate", "type": "object"}, "CustomerBankAccountUpdate": {"additionalProperties": false, "description": "Schema for updating a CustomerBankAccount.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bank account name", "title": "Name"}, "iban": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IBAN number", "title": "Iban"}, "account_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Account number", "title": "Account Number"}, "bank_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bank name", "title": "Bank Name"}, "swift_bic": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SWIFT/BIC code", "title": "Swift Bic"}, "currency_code": {"anyOf": [{"maxLength": 3, "type": "string"}, {"type": "null"}], "description": "Currency code (ISO 4217)", "title": "Currency Code"}, "is_primary": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is primary bank account", "title": "Is Primary"}}, "title": "CustomerBankAccountUpdate", "type": "object"}, "CustomerLocationQueryParams": {"additionalProperties": false, "description": "Query parameters for customer locations endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by relationship type ID", "title": "Relationship Id"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Filter by location type"}}, "title": "CustomerLocationQueryParams", "type": "object"}, "CustomerLocationResponse": {"additionalProperties": false, "description": "Schema for CustomerLocation response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Customer location ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "location": {"$ref": "#/components/schemas/LocationObjectWithType", "description": "Location information"}, "relationship": {"anyOf": [{"$ref": "#/components/schemas/RelationshipTypeObject"}, {"type": "null"}], "description": "Relationship type information"}}, "required": ["updated_at", "id", "customer_id", "location"], "title": "CustomerLocationResponse", "type": "object"}, "LocationObjectWithType": {"additionalProperties": false, "description": "Nested location object for responses (no timestamps), including type.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Location type"}}, "required": ["id"], "title": "LocationObjectWithType", "type": "object"}, "RelationshipTypeObject": {"additionalProperties": false, "description": "Nested relationship type object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["id", "code"], "title": "RelationshipTypeObject", "type": "object"}, "CustomerLocationCreate": {"additionalProperties": false, "description": "Schema for sharing or creating a location in customer context.", "properties": {"mode": {"$ref": "#/components/schemas/CustomerLocationCreateMode", "description": "Create mode: share an existing location or create a new one"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing location ID. Required when mode=share", "title": "Location Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID. Allowed only when mode=share", "title": "Relationship Id"}, "children_relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID for auto-created turbine assignments. Required when mode=share", "title": "Children Relationship Id"}, "name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Location name. Required when mode=create", "title": "Name"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}], "description": "Location type. Required when mode=create"}, "windpark_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Wind park type", "title": "Windpark Type"}, "address_line1": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address line 1. Required when mode=create", "title": "Address Line1"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "City. Required when mode=create", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID. Required when mode=create", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID. Required when mode=create", "title": "Timezone Id"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate. Required when mode=create", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate. Required when mode=create", "title": "Longitude"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Coordinates string", "title": "Coordinates"}, "global_wind_park_db_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Global wind park database ID", "title": "Global Wind Park Db Id"}, "certificates": {"anyOf": [{"items": {"$ref": "#/components/schemas/LocationCertificateInput"}, "type": "array"}, {"type": "null"}], "description": "Required certificates for the location", "title": "Certificates"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Site-specific attributes for the new location (mode=create only). Canonical keys: terrain_type, terrain_details, ground_conditions, regulations, operational_limitations", "title": "Custom Fields"}}, "required": ["mode"], "title": "CustomerLocationCreate", "type": "object"}, "CustomerLocationCreateMode": {"description": "Supported create flows for customer locations.", "enum": ["share", "create"], "title": "CustomerLocationCreateMode", "type": "string"}, "CustomerLocationUpdate": {"additionalProperties": false, "description": "Schema for updating a CustomerLocation.", "properties": {"location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Location ID", "title": "Location Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID", "title": "Relationship Id"}}, "title": "CustomerLocationUpdate", "type": "object"}, "CustomerLocationListQueryParams": {"additionalProperties": false, "description": "Query parameters for the top-level customer-locations list endpoint.\n\nPowers the turbine-create picker on the frontend: given a location, fetch\nthe customers linked to it (each carrying their default relationship_id).", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by relationship type ID", "title": "Relationship Id"}}, "title": "CustomerLocationListQueryParams", "type": "object"}, "CustomerUserResponse": {"additionalProperties": false, "description": "Schema for CustomerUser response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Customer user ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "user": {"$ref": "#/components/schemas/UserObject", "description": "User information"}, "customer_role_ids": {"description": "Assigned role IDs", "items": {"type": "integer"}, "title": "Customer Role Ids", "type": "array"}, "status": {"description": "Membership lifecycle: INVITED | ACTIVE | DECLINED | EXPIRED", "enum": ["INVITED", "ACTIVE", "DECLINED", "EXPIRED"], "title": "Status", "type": "string"}}, "required": ["updated_at", "id", "customer_id", "user", "status"], "title": "CustomerUserResponse", "type": "object"}, "UserObject": {"additionalProperties": false, "description": "Nested user object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "username": {"title": "Username", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "first_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "First Name"}, "last_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Name"}}, "required": ["id", "username"], "title": "UserObject", "type": "object"}, "CustomerUserCreate": {"additionalProperties": false, "description": "Schema for creating a CustomerUser.", "properties": {"user_id": {"description": "User ID", "title": "User Id", "type": "integer"}, "customer_role_ids": {"description": "Role IDs to assign", "items": {"type": "integer"}, "title": "Customer Role Ids", "type": "array"}}, "required": ["user_id"], "title": "CustomerUserCreate", "type": "object"}, "CustomerUserUpdate": {"additionalProperties": false, "description": "Schema for updating a CustomerUser.", "properties": {"user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "User ID", "title": "User Id"}, "customer_role_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Role IDs (None = no change, [] = clear all)", "title": "Customer Role Ids"}}, "title": "CustomerUserUpdate", "type": "object"}, "CustomerRoleResponse": {"additionalProperties": false, "description": "Schema for CustomerRole response (assignable roles for a customer).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Customer role ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "name": {"description": "Role name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Role description", "title": "Description"}, "is_editable": {"default": true, "description": "Whether the role can be edited/deleted", "title": "Is Editable", "type": "boolean"}}, "required": ["updated_at", "id", "customer_id", "name"], "title": "CustomerRoleResponse", "type": "object"}, "CustomerTurbineQueryParams": {"additionalProperties": false, "description": "Query parameters for customer turbines endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by relationship type ID", "title": "Relationship Id"}, "is_virtual": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by virtual turbine", "title": "Is Virtual"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine location ID", "title": "Location Id"}}, "title": "CustomerTurbineQueryParams", "type": "object"}, "CustomerTurbineResponse": {"additionalProperties": false, "description": "Schema for CustomerTurbine response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Customer turbine ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "turbine": {"$ref": "#/components/schemas/TurbineWithLocationObject", "description": "Turbine information with location"}, "relationship": {"anyOf": [{"$ref": "#/components/schemas/RelationshipTypeObject"}, {"type": "null"}], "description": "Relationship type information"}}, "required": ["updated_at", "id", "customer_id", "turbine"], "title": "CustomerTurbineResponse", "type": "object"}, "LocationObject": {"additionalProperties": false, "description": "Nested location object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}]}}, "required": ["id", "name"], "title": "LocationObject", "type": "object"}, "TurbineWithLocationObject": {"additionalProperties": false, "description": "Nested turbine object with location for customer turbine responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationObject"}, {"type": "null"}]}}, "required": ["id"], "title": "TurbineWithLocationObject", "type": "object"}, "CustomerTurbineCreate": {"additionalProperties": false, "description": "Schema for creating or sharing a turbine in customer context.", "properties": {"mode": {"$ref": "#/components/schemas/CustomerTurbineCreateMode", "description": "Create mode: share an existing turbine or create a new one"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing turbine ID. Required when mode=share", "title": "Turbine Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID. Optional in both modes; when omitted in mode=create the server defaults to the customer's customer_locations.relationship_id for the turbine's location.", "title": "Relationship Id"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID. Required when mode=create", "title": "Customer Location Id"}, "name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Turbine name. Required when mode=create", "title": "Name"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate. Required when mode=create", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate. Required when mode=create", "title": "Longitude"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "manufacturer_turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Manufacturer Turbine Model Id"}, "pad_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Pad number", "title": "Pad Number"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "efficiency": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine efficiency", "title": "Efficiency"}, "commissioning_year": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Year of commissioning", "title": "Commissioning Year"}, "output": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine output", "title": "Output"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Coordinates string", "title": "Coordinates"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "components": {"anyOf": [{"items": {"$ref": "#/components/schemas/TurbineComponentInput"}, "type": "array"}, {"type": "null"}], "description": "Optional list of turbine components to create", "title": "Components"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "double_receptors": {"default": false, "description": "Has double receptors", "title": "Double Receptors", "type": "boolean"}, "hv_double_receptors": {"default": false, "description": "Has HV double receptors", "title": "Hv Double Receptors", "type": "boolean"}, "manufacturer_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer number", "title": "Manufacturer Number"}, "is_virtual": {"default": false, "description": "Is virtual turbine", "title": "Is Virtual", "type": "boolean"}}, "required": ["mode"], "title": "CustomerTurbineCreate", "type": "object"}, "CustomerTurbineCreateMode": {"description": "Supported create flows for customer turbines.", "enum": ["share", "create"], "title": "CustomerTurbineCreateMode", "type": "string"}, "PositionEnum": {"description": "Enum for turbine component positions.", "enum": ["A", "B", "C"], "title": "PositionEnum", "type": "string"}, "TurbineComponentInput": {"additionalProperties": false, "description": "Schema for creating a TurbineComponent as part of Turbine creation.\n\nNote: turbine_id and location_id are automatically set from the parent turbine.", "properties": {"component_type_id": {"description": "Component type ID", "title": "Component Type Id", "type": "integer"}, "serial_number": {"description": "Serial number", "minLength": 1, "title": "Serial Number", "type": "string"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component model ID", "title": "Model Id"}, "length": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component length in meters", "title": "Length"}, "position": {"anyOf": [{"$ref": "#/components/schemas/PositionEnum"}, {"type": "null"}], "description": "Component position (A, B, or C). Must be NULL when the selected turbine has is_virtual=true; required when is_virtual=false."}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "description": "1 or 2 for paired receptors; NULL for non-paired components.", "title": "Pair Index"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "required": ["component_type_id", "serial_number"], "title": "TurbineComponentInput", "type": "object"}, "CustomerTurbineUpdate": {"additionalProperties": false, "description": "Schema for updating a CustomerTurbine.", "properties": {"turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID", "title": "Relationship Id"}}, "title": "CustomerTurbineUpdate", "type": "object"}, "DelayCategoryQueryParams": {"additionalProperties": false, "description": "Query parameters for delay categories endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}}, "title": "DelayCategoryQueryParams", "type": "object"}, "DelayCategoryResponse": {"additionalProperties": false, "description": "Schema for DelayCategory response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Delay category ID", "title": "Id", "type": "integer"}, "code": {"description": "Delay category code", "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Category description", "title": "Description"}, "enabled": {"description": "Whether category is enabled", "title": "Enabled", "type": "boolean"}, "include_in_client_reports": {"description": "Include in client reports", "title": "Include In Client Reports", "type": "boolean"}}, "required": ["updated_at", "id", "code", "enabled", "include_in_client_reports"], "title": "DelayCategoryResponse", "type": "object"}, "DelayCategoryCreate": {"additionalProperties": false, "description": "Schema for creating a DelayCategory.", "properties": {"code": {"description": "Delay category code", "minLength": 1, "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Category description", "title": "Description"}, "enabled": {"default": true, "description": "Whether category is enabled", "title": "Enabled", "type": "boolean"}, "include_in_client_reports": {"default": true, "description": "Include in client reports", "title": "Include In Client Reports", "type": "boolean"}}, "required": ["code"], "title": "DelayCategoryCreate", "type": "object"}, "DelayCategoryUpdate": {"additionalProperties": false, "description": "Schema for updating a DelayCategory.", "properties": {"code": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Delay category code", "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Category description", "title": "Description"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether category is enabled", "title": "Enabled"}, "include_in_client_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Include in client reports", "title": "Include In Client Reports"}}, "title": "DelayCategoryUpdate", "type": "object"}, "DelayTypeQueryParams": {"additionalProperties": false, "description": "Query parameters for delay types endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "delay_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by delay category ID", "title": "Delay Category Id"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}}, "title": "DelayTypeQueryParams", "type": "object"}, "DelayCategoryObject": {"additionalProperties": false, "description": "Nested delay category object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "DelayCategoryObject", "type": "object"}, "DelayTypeResponse": {"additionalProperties": false, "description": "Schema for DelayType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Delay type ID", "title": "Id", "type": "integer"}, "delay_category": {"$ref": "#/components/schemas/DelayCategoryObject", "description": "Delay category information"}, "code": {"description": "Delay type code", "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Type description", "title": "Description"}, "enabled": {"description": "Whether type is enabled", "title": "Enabled", "type": "boolean"}, "include_in_client_reports": {"description": "Include in client reports", "title": "Include In Client Reports", "type": "boolean"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields as JSON (object or array)", "title": "Custom Fields"}}, "required": ["updated_at", "id", "delay_category", "code", "enabled", "include_in_client_reports"], "title": "DelayTypeResponse", "type": "object"}, "DelayTypeCreate": {"additionalProperties": false, "description": "Schema for creating a DelayType.", "properties": {"delay_category_id": {"description": "Delay category ID", "title": "Delay Category Id", "type": "integer"}, "code": {"description": "Delay type code", "minLength": 1, "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Type description", "title": "Description"}, "enabled": {"default": true, "description": "Whether type is enabled", "title": "Enabled", "type": "boolean"}, "include_in_client_reports": {"default": true, "description": "Include in client reports", "title": "Include In Client Reports", "type": "boolean"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields as JSON (object or array)", "title": "Custom Fields"}}, "required": ["delay_category_id", "code"], "title": "DelayTypeCreate", "type": "object"}, "DelayTypeUpdate": {"additionalProperties": false, "description": "Schema for updating a DelayType.", "properties": {"delay_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Delay category ID", "title": "Delay Category Id"}, "code": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Delay type code", "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Type description", "title": "Description"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether type is enabled", "title": "Enabled"}, "include_in_client_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Include in client reports", "title": "Include In Client Reports"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields as JSON (object or array)", "title": "Custom Fields"}}, "title": "DelayTypeUpdate", "type": "object"}, "DelayQueryParams": {"additionalProperties": false, "description": "Query parameters for delays endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by comment (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "delay_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by delay type ID", "title": "Delay Type Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by robot set ID", "title": "Robot Set Id"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource ID", "title": "Resource Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order ID", "title": "Service Order Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder ID", "title": "Workorder Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder activity ID", "title": "Workorder Activity Id"}}, "title": "DelayQueryParams", "type": "object"}, "DelayResponse": {"additionalProperties": false, "description": "Schema for Delay response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Delay ID", "title": "Id", "type": "integer"}, "delay_type": {"$ref": "#/components/schemas/DelayTypeObject", "description": "Delay type information"}, "comment": {"description": "Delay comment", "title": "Comment", "type": "string"}, "description": {"default": "", "description": "Delay description", "title": "Description", "type": "string"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Delay start date and time", "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Delay end date and time", "title": "End Datetime"}, "duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Duration in minutes", "title": "Duration Minutes"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields as JSON (object or array)", "title": "Custom Fields"}, "robot_set": {"anyOf": [{"$ref": "#/components/schemas/RobotSetObject"}, {"type": "null"}], "description": "Robot set information (cause)"}, "resource": {"anyOf": [{"$ref": "#/components/schemas/ResourceObject"}, {"type": "null"}], "description": "Resource information (cause)"}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationObject"}, {"type": "null"}], "description": "Location information (cause)"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (impact)", "title": "Project Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID (impact)", "title": "Service Order Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder ID (impact)", "title": "Workorder Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder activity ID (impact)", "title": "Workorder Activity Id"}, "team_resources": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Team resources JSON (same shape as activity resources)", "title": "Team Resources"}, "team_robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Assigned winch set ID (team context, not cause)", "title": "Team Robot Set Id"}}, "required": ["updated_at", "id", "delay_type", "comment"], "title": "DelayResponse", "type": "object"}, "DelayTypeObject": {"additionalProperties": false, "description": "Nested delay type object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "DelayTypeObject", "type": "object"}, "ResourceObject": {"additionalProperties": false, "description": "Nested resource object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "full_name": {"title": "Full Name", "type": "string"}}, "required": ["id", "full_name"], "title": "ResourceObject", "type": "object"}, "RobotSetObject": {"additionalProperties": false, "description": "Nested robot set object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "RobotSetObject", "type": "object"}, "DelayCreate": {"additionalProperties": false, "description": "Schema for creating a Delay.", "properties": {"delay_type_id": {"description": "Delay type ID", "title": "Delay Type Id", "type": "integer"}, "comment": {"description": "Delay comment", "minLength": 1, "title": "Comment", "type": "string"}, "description": {"default": "", "description": "Delay description", "title": "Description", "type": "string"}, "start_datetime": {"description": "Delay start date and time", "format": "date-time", "title": "Start Datetime", "type": "string"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Delay end date and time", "title": "End Datetime"}, "duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Duration in minutes", "title": "Duration Minutes"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields as JSON (object or array)", "title": "Custom Fields"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID (cause)", "title": "Robot Set Id"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource ID (cause)", "title": "Resource Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Location ID (cause)", "title": "Location Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (impact)", "title": "Project Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID (impact)", "title": "Service Order Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder ID (impact)", "title": "Workorder Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder activity ID (impact)", "title": "Workorder Activity Id"}, "team_resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "description": "Team resources JSON (same shape as activity resources)", "title": "Team Resources"}, "team_preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource preset ID \u2014 used to sync WorkorderResource is_lead", "title": "Team Preset Id"}}, "required": ["delay_type_id", "comment", "start_datetime"], "title": "DelayCreate", "type": "object"}, "DelayUpdate": {"additionalProperties": false, "description": "Schema for updating a Delay.", "properties": {"delay_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Delay type ID", "title": "Delay Type Id"}, "comment": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Delay comment", "title": "Comment"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Delay description", "title": "Description"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Delay start date and time", "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Delay end date and time", "title": "End Datetime"}, "duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Duration in minutes", "title": "Duration Minutes"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields as JSON (object or array)", "title": "Custom Fields"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID (cause)", "title": "Robot Set Id"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource ID (cause)", "title": "Resource Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Location ID (cause)", "title": "Location Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (impact)", "title": "Project Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID (impact)", "title": "Service Order Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder ID (impact)", "title": "Workorder Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder activity ID (impact)", "title": "Workorder Activity Id"}, "team_resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "description": "Team resources JSON (same shape as activity resources)", "title": "Team Resources"}, "team_preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource preset ID \u2014 used to sync WorkorderResource is_lead", "title": "Team Preset Id"}}, "title": "DelayUpdate", "type": "object"}, "NotificationCategory": {"description": "The unit a user unsubscribes from.\n\nDeliberately coarse \u2014 the groupings a person reasons about (\"stop emailing me\nabout anomalies\"), not one entry per event. A kind declares its category, and an\nabsent ``NotificationPreference`` row means the defaults apply, so a category\nadded here needs no backfill.", "enum": ["MENTIONS", "PROJECT_READINESS", "ANOMALIES", "SERVICE_DELIVERY", "ROTATIONS"], "title": "NotificationCategory", "type": "string"}, "NotificationQueryParams": {"additionalProperties": false, "description": "Query params for notification list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "is_read": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Read"}, "is_archived": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Archived"}, "category": {"anyOf": [{"$ref": "#/components/schemas/NotificationCategory"}, {"type": "null"}]}}, "title": "NotificationQueryParams", "type": "object"}, "NotificationResponse": {"additionalProperties": false, "description": "Response schema for a notification (list and single endpoints alike).", "properties": {"id": {"title": "Id", "type": "integer"}, "user_id": {"title": "User Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "notification_type": {"title": "Notification Type", "type": "string"}, "action": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Action"}, "kind": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registry code from notifications.notify, e.g. 'comment_mention'. Null only on rows predating the column, which carry it in data['kind'].", "title": "Kind"}, "category": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NotificationCategory the kind belongs to, denormalised.", "title": "Category"}, "entity_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Entity Type"}, "entity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Entity Id"}, "seen_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the row was displayed. Set once, never cleared, and not the same thing as read \u2014 it does not affect the unread count.", "title": "Seen At"}, "is_read": {"title": "Is Read", "type": "boolean"}, "read_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Read At"}, "is_archived": {"title": "Is Archived", "type": "boolean"}, "data": {"title": "Data", "type": "object"}, "metadata": {"description": "Notification-layer extras (action buttons, variants, deep-link overrides), kept separate from the producer-owned 'data' payload.", "title": "Metadata", "type": "object"}, "event_count": {"default": 1, "description": "Occurrences this row stands for; above 1 when the kind collapses.", "title": "Event Count", "type": "integer"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "user_id", "notification_type", "is_read", "is_archived", "data", "created_at"], "title": "NotificationResponse", "type": "object"}, "NotificationUnreadCountResponse": {"additionalProperties": false, "description": "Response for unread notification count.", "properties": {"count": {"title": "Count", "type": "integer"}}, "required": ["count"], "title": "NotificationUnreadCountResponse", "type": "object"}, "NotificationMarkAllReadResponse": {"additionalProperties": false, "description": "Response for mark-all-read action.", "properties": {"updated_count": {"title": "Updated Count", "type": "integer"}}, "required": ["updated_count"], "title": "NotificationMarkAllReadResponse", "type": "object"}, "NotificationSeenResponse": {"additionalProperties": false, "description": "Response for the batch mark-as-seen action.", "properties": {"updated": {"description": "How many rows got a seen_at stamp. Already-seen rows are not re-stamped, so a repeat call returns 0.", "title": "Updated", "type": "integer"}}, "required": ["updated"], "title": "NotificationSeenResponse", "type": "object"}, "NotificationSeenRequest": {"additionalProperties": false, "description": "Body for the batch mark-as-seen action.\n\nThe cap stops one request issuing an unbounded UPDATE; the bell panel only ever\nreports the rows it rendered.", "properties": {"ids": {"description": "Notification ids that were displayed. At most 200 per call; ids belonging to another user are ignored.", "items": {"type": "integer"}, "maxItems": 200, "title": "Ids", "type": "array"}}, "required": ["ids"], "title": "NotificationSeenRequest", "type": "object"}, "NotificationPreferenceItem": {"additionalProperties": false, "description": "One category's channel opt-outs, used for both request and response.\n\nThe response always carries every category; the upsert body requires both\nchannels so an omitted field cannot silently re-enable one.", "properties": {"category": {"$ref": "#/components/schemas/NotificationCategory"}, "email": {"title": "Email", "type": "boolean"}, "push": {"title": "Push", "type": "boolean"}}, "required": ["category", "email", "push"], "title": "NotificationPreferenceItem", "type": "object"}, "NotificationUpdate": {"additionalProperties": false, "description": "Schema for updating notification read/archived status.", "properties": {"is_read": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Read"}, "is_archived": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Archived"}}, "title": "NotificationUpdate", "type": "object"}, "EventResult": {"additionalProperties": false, "description": "``announced`` is False for an event that produced nothing this time.", "properties": {"announced": {"title": "Announced", "type": "boolean"}}, "required": ["announced"], "title": "EventResult", "type": "object"}, "EventRequest": {"additionalProperties": false, "description": "An event id off the menu in ``EVENTS``, plus that event's parameters.", "properties": {"event": {"title": "Event", "type": "string"}, "params": {"default": {}, "title": "Params", "type": "object"}}, "required": ["event"], "title": "EventRequest", "type": "object"}, "FileEntityLinkQueryParams": {"additionalProperties": false, "description": "Query parameters for file entity links endpoint.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "file_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by file ID", "title": "File Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder activity ID", "title": "Workorder Activity Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order line ID", "title": "Service Order Line Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order ID", "title": "Service Order Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine component ID", "title": "Turbine Component Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly ID", "title": "Anomaly Id"}, "service_result_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service result ID", "title": "Service Result Id"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer location ID", "title": "Customer Location Id"}}, "title": "FileEntityLinkQueryParams", "type": "object"}, "FileEntityLinkResponse": {"additionalProperties": false, "description": "Schema for FileEntityLink response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Record ID", "title": "Id", "type": "integer"}, "file_id": {"description": "File ID", "title": "File Id", "type": "integer"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder activity ID", "title": "Workorder Activity Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID", "title": "Service Order Line Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID", "title": "Service Order Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly ID", "title": "Anomaly Id"}, "service_result_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service result ID", "title": "Service Result Id"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "required": ["updated_at", "id", "file_id"], "title": "FileEntityLinkResponse", "type": "object"}, "FileEntityLinkCreate": {"additionalProperties": false, "description": "Schema for creating a FileEntityLink.", "properties": {"file_id": {"description": "File ID", "title": "File Id", "type": "integer"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder activity ID", "title": "Workorder Activity Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID", "title": "Service Order Line Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID", "title": "Service Order Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly ID", "title": "Anomaly Id"}, "service_result_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service result ID", "title": "Service Result Id"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "required": ["file_id"], "title": "FileEntityLinkCreate", "type": "object"}, "FileEntityLinkUpdate": {"additionalProperties": false, "description": "Schema for updating a FileEntityLink.", "properties": {"workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder activity ID", "title": "Workorder Activity Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Workorder ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID", "title": "Service Order Line Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID", "title": "Service Order Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly ID", "title": "Anomaly Id"}, "service_result_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service result ID", "title": "Service Result Id"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "title": "FileEntityLinkUpdate", "type": "object"}, "TurbineImportResponse": {"additionalProperties": false, "properties": {"created_count": {"default": 0, "title": "Created Count", "type": "integer"}, "errors": {"default": [], "items": {"$ref": "#/components/schemas/TurbineImportRowError"}, "title": "Errors", "type": "array"}}, "title": "TurbineImportResponse", "type": "object"}, "TurbineImportRowError": {"additionalProperties": false, "properties": {"row": {"title": "Row", "type": "integer"}, "errors": {"items": {"type": "string"}, "title": "Errors", "type": "array"}}, "required": ["row", "errors"], "title": "TurbineImportRowError", "type": "object"}, "TurbineQueryParams": {"additionalProperties": false, "description": "Query parameters for turbines endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "manufacturer_turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine model ID", "title": "Manufacturer Turbine Model Id"}, "is_virtual": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by virtual turbine", "title": "Is Virtual"}, "health": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated health levels (0=NO_DATA, 100=HEALTHY, 20=ATTENTION_NEEDED, 30=ACTION_REQUIRED)", "title": "Health"}, "ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated turbine IDs \u2014 returns only turbines whose id is in the list (batch fetch by id)", "title": "Ids"}}, "title": "TurbineQueryParams", "type": "object"}, "TurbineModelObject": {"additionalProperties": false, "description": "Nested turbine model object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "TurbineModelObject", "type": "object"}, "TurbineResponse": {"additionalProperties": false, "description": "Schema for Turbine response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Turbine ID", "title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Name"}, "location": {"$ref": "#/components/schemas/LocationObject", "description": "Location information"}, "manufacturer": {"anyOf": [{"$ref": "#/components/schemas/ManufacturerObject"}, {"type": "null"}], "description": "Manufacturer information"}, "model": {"anyOf": [{"$ref": "#/components/schemas/TurbineModelObject"}, {"type": "null"}], "description": "Turbine model information"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate", "title": "Longitude"}, "pad_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Pad number", "title": "Pad Number"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "efficiency": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine efficiency", "title": "Efficiency"}, "commissioning_year": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Year of commissioning", "title": "Commissioning Year"}, "output": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine output", "title": "Output"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Coordinates string", "title": "Coordinates"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "double_receptors": {"description": "Has double receptors", "title": "Double Receptors", "type": "boolean"}, "hv_double_receptors": {"description": "Has HV double receptors", "title": "Hv Double Receptors", "type": "boolean"}, "manufacturer_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer number", "title": "Manufacturer Number"}, "is_virtual": {"description": "Is virtual turbine", "title": "Is Virtual", "type": "boolean"}}, "required": ["updated_at", "id", "location", "double_receptors", "hv_double_receptors", "is_virtual"], "title": "TurbineResponse", "type": "object"}, "TurbineCreate": {"additionalProperties": false, "description": "Schema for creating a Turbine.", "properties": {"name": {"description": "Turbine name", "minLength": 1, "title": "Name", "type": "string"}, "location_id": {"description": "Location ID", "title": "Location Id", "type": "integer"}, "latitude": {"description": "Latitude coordinate", "title": "Latitude", "type": "number"}, "longitude": {"description": "Longitude coordinate", "title": "Longitude", "type": "number"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "manufacturer_turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Manufacturer Turbine Model Id"}, "pad_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Pad number", "title": "Pad Number"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "efficiency": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine efficiency", "title": "Efficiency"}, "commissioning_year": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Year of commissioning", "title": "Commissioning Year"}, "output": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine output", "title": "Output"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Coordinates string", "title": "Coordinates"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "components": {"anyOf": [{"items": {"$ref": "#/components/schemas/TurbineComponentInput"}, "type": "array"}, {"type": "null"}], "description": "Optional list of turbine components to create", "title": "Components"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "manufacturer_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer number", "title": "Manufacturer Number"}, "is_virtual": {"default": false, "description": "Is virtual turbine", "title": "Is Virtual", "type": "boolean"}, "customers": {"description": "Customer assignments. At least one is required; each entry creates a corresponding row in core.customer_turbines.", "items": {"$ref": "#/components/schemas/TurbineCustomerInput"}, "minItems": 1, "title": "Customers", "type": "array"}}, "required": ["name", "location_id", "latitude", "longitude", "customers"], "title": "TurbineCreate", "type": "object"}, "TurbineCustomerInput": {"additionalProperties": false, "description": "Customer assignment payload entry for Turbine creation.", "properties": {"customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID. If null, defaults to the relationship the customer has with the turbine's location (customer_locations.relationship_id).", "title": "Relationship Id"}}, "required": ["customer_id"], "title": "TurbineCustomerInput", "type": "object"}, "TurbineUpdate": {"additionalProperties": false, "description": "Schema for updating a Turbine.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Name"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Location ID", "title": "Location Id"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate", "title": "Longitude"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "manufacturer_turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Manufacturer Turbine Model Id"}, "pad_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Pad number", "title": "Pad Number"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional information", "title": "Additional Info"}, "efficiency": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine efficiency", "title": "Efficiency"}, "commissioning_year": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Year of commissioning", "title": "Commissioning Year"}, "output": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine output", "title": "Output"}, "coordinates": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Coordinates string", "title": "Coordinates"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Hub height in meters", "title": "Hub Height"}, "rotor_radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Rotor radius in meters", "title": "Rotor Radius"}, "nominal_power": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Nominal power in kW", "title": "Nominal Power"}, "manufacturer_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer number", "title": "Manufacturer Number"}, "is_virtual": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is virtual turbine", "title": "Is Virtual"}}, "title": "TurbineUpdate", "type": "object"}, "ComponentImportResponse": {"additionalProperties": false, "properties": {"created_count": {"default": 0, "title": "Created Count", "type": "integer"}, "errors": {"default": [], "items": {"$ref": "#/components/schemas/ComponentImportRowError"}, "title": "Errors", "type": "array"}}, "title": "ComponentImportResponse", "type": "object"}, "ComponentImportRowError": {"additionalProperties": false, "properties": {"row": {"title": "Row", "type": "integer"}, "errors": {"items": {"type": "string"}, "title": "Errors", "type": "array"}}, "required": ["row", "errors"], "title": "ComponentImportRowError", "type": "object"}, "TurbineComponentReassignmentHistoryResponse": {"additionalProperties": false, "description": "Response schema for a single blade component reassignment event.", "properties": {"reassigned_at": {"format": "date-time", "title": "Reassigned At", "type": "string"}, "from_turbine": {"$ref": "#/components/schemas/TurbineObject"}, "to_turbine": {"$ref": "#/components/schemas/TurbineObject"}, "reassigned_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}]}}, "required": ["reassigned_at", "from_turbine", "to_turbine", "reassigned_by"], "title": "TurbineComponentReassignmentHistoryResponse", "type": "object"}, "TurbineObject": {"additionalProperties": false, "description": "Nested turbine object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "TurbineObject", "type": "object"}, "TurbineComponentQueryParams": {"additionalProperties": false, "description": "Query parameters for turbine components endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by serial number (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component type ID", "title": "Component Type Id"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by manufacturer ID", "title": "Manufacturer Id"}, "model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component model ID", "title": "Model Id"}, "parent_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent turbine component ID", "title": "Parent Turbine Component Id"}}, "title": "TurbineComponentQueryParams", "type": "object"}, "ManufacturerComponentModelObject": {"additionalProperties": false, "description": "Nested manufacturer component model object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ManufacturerComponentModelObject", "type": "object"}, "TurbineComponentResponse": {"additionalProperties": false, "description": "Schema for TurbineComponent response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Turbine component ID", "title": "Id", "type": "integer"}, "component_type": {"$ref": "#/components/schemas/ComponentTypeObject", "description": "Component type information"}, "serial_number": {"description": "Serial number", "title": "Serial Number", "type": "string"}, "manufacturer_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer serial number", "title": "Manufacturer Serial Number"}, "manufacturer": {"anyOf": [{"$ref": "#/components/schemas/ManufacturerObject"}, {"type": "null"}], "description": "Manufacturer information"}, "model": {"anyOf": [{"$ref": "#/components/schemas/ManufacturerComponentModelObject"}, {"type": "null"}], "description": "Component model information"}, "turbine": {"$ref": "#/components/schemas/TurbineObject", "description": "Turbine information"}, "parent_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent turbine component ID", "title": "Parent Turbine Component Id"}, "length": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component length in meters", "title": "Length"}, "radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component radius in meters", "title": "Radius"}, "blade_tip": {"description": "Whether this is a blade tip component", "title": "Blade Tip", "type": "boolean"}, "position": {"anyOf": [{"$ref": "#/components/schemas/PositionEnum"}, {"type": "null"}], "description": "Component position (A, B, or C)"}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "description": "1 or 2 for paired receptors; NULL for non-paired components.", "title": "Pair Index"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "required": ["updated_at", "id", "component_type", "serial_number", "turbine", "blade_tip"], "title": "TurbineComponentResponse", "type": "object"}, "TurbineComponentCreate": {"additionalProperties": false, "description": "Schema for creating a TurbineComponent.", "properties": {"component_type_id": {"description": "Component type ID", "title": "Component Type Id", "type": "integer"}, "serial_number": {"description": "Serial number", "minLength": 1, "title": "Serial Number", "type": "string"}, "manufacturer_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer serial number", "title": "Manufacturer Serial Number"}, "turbine_id": {"description": "Turbine ID", "title": "Turbine Id", "type": "integer"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component model ID", "title": "Model Id"}, "parent_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent turbine component ID", "title": "Parent Turbine Component Id"}, "length": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component length in meters", "title": "Length"}, "radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component radius in meters", "title": "Radius"}, "blade_tip": {"default": false, "description": "Whether this is a blade tip component", "title": "Blade Tip", "type": "boolean"}, "position": {"anyOf": [{"$ref": "#/components/schemas/PositionEnum"}, {"type": "null"}], "description": "Component position (A, B, or C). Must be NULL when the selected turbine has is_virtual=true; required when is_virtual=false."}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "description": "1 or 2 for paired receptors; NULL for non-paired components.", "title": "Pair Index"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "required": ["component_type_id", "serial_number", "turbine_id"], "title": "TurbineComponentCreate", "type": "object"}, "TurbineComponentUpdate": {"additionalProperties": false, "description": "Schema for updating a TurbineComponent.", "properties": {"component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID", "title": "Component Type Id"}, "serial_number": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Serial number", "title": "Serial Number"}, "manufacturer_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer serial number", "title": "Manufacturer Serial Number"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer ID", "title": "Manufacturer Id"}, "model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component model ID", "title": "Model Id"}, "parent_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent turbine component ID", "title": "Parent Turbine Component Id"}, "length": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component length in meters", "title": "Length"}, "radius": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Component radius in meters", "title": "Radius"}, "blade_tip": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether this is a blade tip component", "title": "Blade Tip"}, "position": {"anyOf": [{"$ref": "#/components/schemas/PositionEnum"}, {"type": "null"}], "description": "Component position (A, B, or C)"}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "description": "1 or 2 for paired receptors; NULL for non-paired components.", "title": "Pair Index"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "title": "TurbineComponentUpdate", "type": "object"}, "CertificateQueryParams": {"additionalProperties": false, "description": "Query parameters for certificates endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by category", "title": "Category Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country", "title": "Country Id"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active flag", "title": "Is Active"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by origin system", "title": "Source"}}, "title": "CertificateQueryParams", "type": "object"}, "CertificateResponse": {"additionalProperties": false, "description": "Schema for Certificate response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Certificate ID", "title": "Id", "type": "integer"}, "name": {"description": "Certificate name", "title": "Name", "type": "string"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Unique short code", "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "default_validity_months": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Default expiry window in months", "title": "Default Validity Months"}, "is_active": {"description": "Whether the certificate is active", "title": "Is Active", "type": "boolean"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country FK", "title": "Country Id"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Category FK", "title": "Category Id"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Origin system", "title": "Source"}}, "required": ["updated_at", "id", "name", "is_active"], "title": "CertificateResponse", "type": "object"}, "CertificateCreate": {"additionalProperties": false, "description": "Schema for creating a Certificate.", "properties": {"name": {"description": "Certificate name", "minLength": 1, "title": "Name", "type": "string"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Unique short code", "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "default_validity_months": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Default expiry window in months. Omit / null for non-expiring certificates.", "title": "Default Validity Months"}, "is_active": {"default": true, "description": "Whether the certificate is active", "title": "Is Active", "type": "boolean"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country the certificate is intrinsic to. Omit for global.", "title": "Country Id"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Category FK", "title": "Category Id"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Origin system (e.g. \"bamboohr\")", "title": "Source"}}, "required": ["name"], "title": "CertificateCreate", "type": "object"}, "CertificateUpdate": {"additionalProperties": false, "description": "Schema for updating a Certificate (partial).", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "default_validity_months": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Default Validity Months"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Active"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source"}}, "title": "CertificateUpdate", "type": "object"}, "CertificateCategoryQueryParams": {"additionalProperties": false, "description": "Query parameters for certificate-categories endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "CertificateCategoryQueryParams", "type": "object"}, "CertificateCategoryResponse": {"additionalProperties": false, "description": "Schema for CertificateCategory response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "color": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Color"}, "sort_order": {"title": "Sort Order", "type": "integer"}}, "required": ["updated_at", "id", "name", "sort_order"], "title": "CertificateCategoryResponse", "type": "object"}, "CertificateCategoryCreate": {"additionalProperties": false, "description": "Schema for creating a CertificateCategory.", "properties": {"name": {"description": "Category name", "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "color": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display color", "title": "Color"}, "sort_order": {"default": 0, "description": "Display sort order", "title": "Sort Order", "type": "integer"}}, "required": ["name"], "title": "CertificateCategoryCreate", "type": "object"}, "CertificateCategoryUpdate": {"additionalProperties": false, "description": "Schema for updating a CertificateCategory (partial).", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "color": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Color"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}}, "title": "CertificateCategoryUpdate", "type": "object"}, "CertificateIssuerQueryParams": {"additionalProperties": false, "description": "Query parameters for certificate-issuers endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country", "title": "Country Id"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active flag", "title": "Is Active"}}, "title": "CertificateIssuerQueryParams", "type": "object"}, "CertificateIssuerResponse": {"additionalProperties": false, "description": "Schema for CertificateIssuer response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "website": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Website"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}, "is_active": {"title": "Is Active", "type": "boolean"}}, "required": ["updated_at", "id", "name", "is_active"], "title": "CertificateIssuerResponse", "type": "object"}, "CertificateIssuerCreate": {"additionalProperties": false, "description": "Schema for creating a CertificateIssuer.", "properties": {"name": {"description": "Issuer name", "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "website": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Website"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}, "is_active": {"default": true, "title": "Is Active", "type": "boolean"}}, "required": ["name"], "title": "CertificateIssuerCreate", "type": "object"}, "CertificateIssuerUpdate": {"additionalProperties": false, "description": "Schema for updating a CertificateIssuer (partial).", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "website": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Website"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Active"}}, "title": "CertificateIssuerUpdate", "type": "object"}, "CertificateOfferingQueryParams": {"additionalProperties": false, "description": "Query parameters for certificate-offerings endpoint.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by certificate", "title": "Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by issuer", "title": "Issuer Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country", "title": "Country Id"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active flag", "title": "Is Active"}}, "title": "CertificateOfferingQueryParams", "type": "object"}, "CertificateOfferingResponse": {"additionalProperties": false, "description": "Schema for CertificateOffering response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "certificate_id": {"title": "Certificate Id", "type": "integer"}, "issuer_id": {"title": "Issuer Id", "type": "integer"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "validity_months": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Validity Months"}, "format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Format"}, "duration": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Duration"}, "how_to_acquire": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "How To Acquire"}, "booking_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Booking Url"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}, "is_active": {"title": "Is Active", "type": "boolean"}}, "required": ["updated_at", "id", "certificate_id", "issuer_id", "is_active"], "title": "CertificateOfferingResponse", "type": "object"}, "CertificateOfferingCreate": {"additionalProperties": false, "description": "Schema for creating a CertificateOffering.", "properties": {"certificate_id": {"description": "Certificate FK", "title": "Certificate Id", "type": "integer"}, "issuer_id": {"description": "Issuer FK", "title": "Issuer Id", "type": "integer"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "validity_months": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Overrides Certificate.default_validity_months", "title": "Validity Months"}, "format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Format"}, "duration": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Duration"}, "how_to_acquire": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "How To Acquire"}, "booking_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Booking Url"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}, "is_active": {"default": true, "title": "Is Active", "type": "boolean"}}, "required": ["certificate_id", "issuer_id"], "title": "CertificateOfferingCreate", "type": "object"}, "CertificateOfferingUpdate": {"additionalProperties": false, "description": "Schema for updating a CertificateOffering (partial).", "properties": {"certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Issuer Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "validity_months": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Validity Months"}, "format": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Format"}, "duration": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Duration"}, "how_to_acquire": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "How To Acquire"}, "booking_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Booking Url"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Active"}}, "title": "CertificateOfferingUpdate", "type": "object"}, "CertificateExpenseQueryParams": {"additionalProperties": false, "description": "Query parameters for certificate-expenses endpoint.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource", "title": "Resource Id"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by certificate", "title": "Certificate Id"}, "resource_certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by linked issuance row", "title": "Resource Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by issuer", "title": "Issuer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project", "title": "Project Id"}, "status": {"anyOf": [{"$ref": "#/components/schemas/CertificateExpenseStatus"}, {"type": "null"}], "description": "Filter by status"}}, "title": "CertificateExpenseQueryParams", "type": "object"}, "CertificateExpenseStatus": {"description": "Lifecycle of a certificate cost row.", "enum": ["PENDING", "COMPLETED", "CANCELLED"], "title": "CertificateExpenseStatus", "type": "string"}, "CertificateExpenseResponse": {"additionalProperties": false, "description": "Schema for CertificateExpense response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "resource_id": {"title": "Resource Id", "type": "integer"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Certificate Id"}, "resource_certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Issuer Id"}, "issuer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Issuer Name"}, "offering_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Offering Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "currency_id": {"title": "Currency Id", "type": "integer"}, "status": {"$ref": "#/components/schemas/CertificateExpenseStatus"}, "order_date": {"format": "date", "title": "Order Date", "type": "string"}, "completion_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completion Date"}, "invoice_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Invoice Number"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reason"}}, "required": ["updated_at", "id", "resource_id", "amount", "currency_id", "status", "order_date"], "title": "CertificateExpenseResponse", "type": "object"}, "CertificateExpenseCreate": {"additionalProperties": false, "description": "Schema for creating a CertificateExpense.", "properties": {"resource_id": {"description": "Resource (technician) FK", "title": "Resource Id", "type": "integer"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Target certificate. Omit for ad-hoc bookings.", "title": "Certificate Id"}, "resource_certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Issuance row, once it exists", "title": "Resource Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Issuer Id"}, "issuer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text fallback when the issuer is not yet matched", "title": "Issuer Name"}, "offering_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Offering Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "description": "Amount in `currency`", "title": "Amount"}, "currency_id": {"description": "Currency FK", "title": "Currency Id", "type": "integer"}, "status": {"allOf": [{"$ref": "#/components/schemas/CertificateExpenseStatus"}], "default": "PENDING", "description": "Lifecycle status"}, "order_date": {"description": "When the cost was booked", "format": "date", "title": "Order Date", "type": "string"}, "completion_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completion Date"}, "invoice_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Invoice Number"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Reason for cancellation / refund / reissue", "title": "Reason"}}, "required": ["resource_id", "amount", "currency_id", "order_date"], "title": "CertificateExpenseCreate", "type": "object"}, "CertificateExpenseUpdate": {"additionalProperties": false, "description": "Schema for updating a CertificateExpense (partial).", "properties": {"resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Certificate Id"}, "resource_certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Certificate Id"}, "issuer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Issuer Id"}, "issuer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Issuer Name"}, "offering_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Offering Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Amount"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "status": {"anyOf": [{"$ref": "#/components/schemas/CertificateExpenseStatus"}, {"type": "null"}]}, "order_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Order Date"}, "completion_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completion Date"}, "invoice_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Invoice Number"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reason"}}, "title": "CertificateExpenseUpdate", "type": "object"}, "AnomalyComponentQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyComponent list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "inspection_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by inspection type", "title": "Inspection Type"}}, "title": "AnomalyComponentQueryParams", "type": "object"}, "AnomalyComponentResponse": {"additionalProperties": false, "description": "Schema for AnomalyComponent response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Component ID", "title": "Id", "type": "integer"}, "name": {"description": "Component name", "title": "Name", "type": "string"}, "inspection_type": {"description": "Inspection type", "title": "Inspection Type", "type": "string"}, "parent_anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent component ID", "title": "Parent Anomaly Component Id"}}, "required": ["updated_at", "id", "name", "inspection_type"], "title": "AnomalyComponentResponse", "type": "object"}, "AnomalyTypeQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyType list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "inspection_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by inspection type", "title": "Inspection Type"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code context. Omit for general/cross-service views (all types returned). When a non-LER- code is supplied, LER QC deviation types are excluded. When a LER- code is supplied, all types are returned.", "title": "Service Code"}}, "title": "AnomalyTypeQueryParams", "type": "object"}, "AnomalyTypeResponse": {"additionalProperties": false, "description": "Schema for AnomalyType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Type ID", "title": "Id", "type": "integer"}, "name": {"description": "Type name", "title": "Name", "type": "string"}, "inspection_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Inspection type", "title": "Inspection Type"}, "parent_anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent type ID", "title": "Parent Anomaly Type Id"}}, "required": ["updated_at", "id", "name"], "title": "AnomalyTypeResponse", "type": "object"}, "AnomalyRootCauseTypeQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyRootCauseType list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in title", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}}, "title": "AnomalyRootCauseTypeQueryParams", "type": "object"}, "AnomalyRootCauseTypeResponse": {"additionalProperties": false, "description": "Schema for AnomalyRootCauseType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Root cause type ID", "title": "Id", "type": "integer"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Root cause title", "title": "Title"}}, "required": ["updated_at", "id"], "title": "AnomalyRootCauseTypeResponse", "type": "object"}, "AnomalyParentTypeQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyParentType list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}}, "title": "AnomalyParentTypeQueryParams", "type": "object"}, "AnomalyParentTypeResponse": {"additionalProperties": false, "description": "Schema for AnomalyParentType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Parent type ID", "title": "Id", "type": "integer"}, "name": {"description": "Parent type name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "name"], "title": "AnomalyParentTypeResponse", "type": "object"}, "AnomalyMaterialQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyMaterial list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly type ID", "title": "Anomaly Type Id"}}, "title": "AnomalyMaterialQueryParams", "type": "object"}, "AnomalyMaterialResponse": {"additionalProperties": false, "description": "Schema for AnomalyMaterial response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Material ID", "title": "Id", "type": "integer"}, "name": {"description": "Material name", "title": "Name", "type": "string"}, "anomaly_type_id": {"description": "Anomaly type ID", "title": "Anomaly Type Id", "type": "integer"}}, "required": ["updated_at", "id", "name", "anomaly_type_id"], "title": "AnomalyMaterialResponse", "type": "object"}, "AnomalyComponentTypeMapQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyComponentTypeMap list.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly component ID", "title": "Anomaly Component Id"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly type ID", "title": "Anomaly Type Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code context. Omit for general/cross-service views (all mappings returned). When a non-LER- code is supplied, mappings to LER QC deviation types are excluded. When a LER- code is supplied, all mappings are returned.", "title": "Service Code"}}, "title": "AnomalyComponentTypeMapQueryParams", "type": "object"}, "AnomalyComponentTypeMapResponse": {"additionalProperties": false, "description": "Schema for AnomalyComponentTypeMap response.", "properties": {"anomaly_component_id": {"description": "Anomaly component ID", "title": "Anomaly Component Id", "type": "integer"}, "anomaly_type_id": {"description": "Anomaly type ID", "title": "Anomaly Type Id", "type": "integer"}}, "required": ["anomaly_component_id", "anomaly_type_id"], "title": "AnomalyComponentTypeMapResponse", "type": "object"}, "AnomalyRecommendationQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyRecommendation list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by type", "title": "Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}}, "title": "AnomalyRecommendationQueryParams", "type": "object"}, "AnomalyRecommendationResponse": {"additionalProperties": false, "description": "Schema for AnomalyRecommendation response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Recommendation ID", "title": "Id", "type": "integer"}, "name": {"description": "Recommendation name", "title": "Name", "type": "string"}, "action": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Recommended action", "title": "Action"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Recommendation type", "title": "Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Recommendation status", "title": "Status"}}, "required": ["updated_at", "id", "name"], "title": "AnomalyRecommendationResponse", "type": "object"}, "AnomalyRecommendationCreate": {"additionalProperties": false, "description": "Schema for creating AnomalyRecommendation.", "properties": {"name": {"description": "Recommendation name", "title": "Name", "type": "string"}, "action": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Recommended action", "title": "Action"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Recommendation type", "title": "Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Recommendation status", "title": "Status"}}, "required": ["name"], "title": "AnomalyRecommendationCreate", "type": "object"}, "AnomalyRecommendationUpdate": {"additionalProperties": false, "description": "Schema for updating AnomalyRecommendation.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "action": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Action"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "title": "AnomalyRecommendationUpdate", "type": "object"}, "AnomalyClientFieldQueryParams": {"additionalProperties": false, "description": "Query parameters for AnomalyClientField list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by field type", "title": "Type"}}, "title": "AnomalyClientFieldQueryParams", "type": "object"}, "AnomalyClientFieldResponse": {"additionalProperties": false, "description": "Schema for AnomalyClientField response (customer custom-field definition).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Custom field ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Owning customer ID", "title": "Customer Id", "type": "integer"}, "customer_display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Owning customer display name, for labelling the field group", "title": "Customer Display Name"}, "name": {"description": "Field name", "title": "Name", "type": "string"}, "type": {"description": "Field data type", "title": "Type", "type": "string"}, "options": {"anyOf": [{"items": {"$ref": "#/components/schemas/CustomerCustomFieldOption"}, "type": "array"}, {"type": "null"}], "description": "Allowed options for SELECT-type fields. A field reading its options from a live list carries the list resolved for this record.", "title": "Options"}, "options_source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The live list a SELECT field reads its options from, or null for a field storing its own. When set, an empty options list means no value is allowed; when null, an empty list leaves the field unrestricted.", "title": "Options Source"}, "validation": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Limits the value must satisfy, as {min, max, decimals}. Applies to NUMBER fields; decimals 0 means whole numbers only.", "title": "Validation"}}, "required": ["updated_at", "id", "customer_id", "name", "type"], "title": "AnomalyClientFieldResponse", "type": "object"}, "CustomerCustomFieldOption": {"additionalProperties": false, "description": "One allowed option for a SELECT-type customer custom field.", "properties": {"value": {"description": "Stored option value", "title": "Value", "type": "string"}, "label": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Human-readable option label", "title": "Label"}}, "required": ["value"], "title": "CustomerCustomFieldOption", "type": "object"}, "AnomalyClientFieldCreate": {"additionalProperties": false, "description": "Schema for creating an AnomalyClientField.", "properties": {"name": {"description": "Field name", "title": "Name", "type": "string"}, "type": {"default": "TEXT", "description": "Field data type", "title": "Type", "type": "string"}, "options": {"anyOf": [{"items": {"$ref": "#/components/schemas/AnomalyClientFieldOption"}, "type": "array"}, {"type": "null"}], "description": "Allowed options for SELECT-type fields", "title": "Options"}}, "required": ["name"], "title": "AnomalyClientFieldCreate", "type": "object"}, "AnomalyClientFieldOption": {"additionalProperties": false, "description": "One allowed option for a SELECT-type client field.", "properties": {"value": {"description": "Stored option value", "title": "Value", "type": "string"}, "label": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Human-readable option label", "title": "Label"}}, "required": ["value"], "title": "AnomalyClientFieldOption", "type": "object"}, "AnomalyClientFieldUpdate": {"additionalProperties": false, "description": "Schema for updating an AnomalyClientField.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Field name", "title": "Name"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Field data type", "title": "Type"}, "options": {"anyOf": [{"items": {"$ref": "#/components/schemas/AnomalyClientFieldOption"}, "type": "array"}, {"type": "null"}], "description": "Allowed options for SELECT-type fields", "title": "Options"}}, "title": "AnomalyClientFieldUpdate", "type": "object"}, "AnomalyFileQueryParams": {"additionalProperties": false, "description": "Query parameters for Anomaly file list.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by file type", "title": "Type"}}, "title": "AnomalyFileQueryParams", "type": "object"}, "FileResponse": {"additionalProperties": false, "description": "Schema for File response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "File ID", "title": "Id", "type": "integer"}, "name": {"description": "File name", "title": "Name", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "File type", "title": "Type"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Extra metadata from the entity link", "title": "Additional Information"}}, "required": ["updated_at", "id", "name"], "title": "FileResponse", "type": "object"}, "BodyFile": {"properties": {"b64data": {"title": "B64Data", "type": "string"}, "name": {"title": "Name", "type": "string"}, "content_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Content Type"}}, "required": ["b64data", "name"], "title": "BodyFile", "type": "object"}, "BodyFileWrapper": {"description": "Object form of a base64 upload request body.\n\nWraps the file list together with optional batch-level\n``additional_information`` metadata that is persisted on every\n``FileEntityLink`` created for the batch (mirroring the multipart\n``additional_information`` form field).", "properties": {"files": {"items": {"$ref": "#/components/schemas/BodyFile"}, "title": "Files", "type": "array"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Additional Information"}}, "required": ["files"], "title": "BodyFileWrapper", "type": "object"}, "AnomalyQueryParams": {"additionalProperties": false, "description": "Query parameters for Anomaly list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text search", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine component ID", "title": "Turbine Component Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by work order ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service order line ID", "title": "Service Order Line Id"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly type ID", "title": "Anomaly Type Id"}, "anomaly_sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by anomaly sub-type ID", "title": "Anomaly Sub Type Id"}, "anomaly_major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by major component ID", "title": "Anomaly Major Component Id"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component ID", "title": "Anomaly Component Id"}, "anomaly_sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sub-component ID", "title": "Anomaly Sub Component Id"}, "anomaly_material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by material ID", "title": "Anomaly Material Id"}, "parent_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by parent type ID", "title": "Parent Type Id"}, "root_cause_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by root cause ID", "title": "Root Cause Id"}, "parent_anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "deprecated": true, "description": "Deprecated: No longer used. Filter by link_group instead.", "title": "Parent Anomaly Id"}, "severity": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by severity", "title": "Severity"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "client_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client status", "title": "Client Status"}, "stage": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by stage", "title": "Stage"}, "internal_external": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by internal/external", "title": "Internal External"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by side", "title": "Side"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by rib", "title": "Rib"}, "cross_section_side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by cross section side", "title": "Cross Section Side"}, "cross_section_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by cross section type", "title": "Cross Section Type"}, "registered_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by registered by", "title": "Registered By"}, "registration_origin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by registration origin", "title": "Registration Origin"}, "created_at_gte": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by creation date >= (YYYY-MM-DD)", "title": "Created At Gte"}, "created_at_lte": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by creation date <= (YYYY-MM-DD)", "title": "Created At Lte"}, "updated_at_gte": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by last modified date >= (YYYY-MM-DD)", "title": "Updated At Gte"}, "updated_at_lte": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by last modified date <= (YYYY-MM-DD)", "title": "Updated At Lte"}, "custom_value_filters": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client custom field values. A JSON array of {\"custom_field_id\": int, \"values\": [str, ...]}; criteria are AND-ed across fields and values are OR-ed within a field. Requires service_order_line_id, whose customer + turbine model gate which fields may be filtered on (a hidden field is rejected).", "title": "Custom Value Filters"}}, "title": "AnomalyQueryParams", "type": "object"}, "AnomalyCustomValueOutput": {"additionalProperties": false, "description": "Schema for a custom field value in an anomaly response.", "properties": {"id": {"description": "Custom value ID", "title": "Id", "type": "integer"}, "custom_field_id": {"description": "Customer custom field ID", "title": "Custom Field Id", "type": "integer"}, "custom_field_name": {"description": "Field name", "title": "Custom Field Name", "type": "string"}, "custom_field_type": {"description": "Field data type", "title": "Custom Field Type", "type": "string"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Value for the field", "title": "Value"}}, "required": ["id", "custom_field_id", "custom_field_name", "custom_field_type"], "title": "AnomalyCustomValueOutput", "type": "object"}, "AnomalyResponse": {"additionalProperties": false, "description": "Schema for Anomaly response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Anomaly ID", "title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly name", "title": "Name"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "turbine_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component display name", "title": "Turbine Component Name"}, "turbine_component_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component serial number", "title": "Turbine Component Serial Number"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Work order ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID", "title": "Service Order Line Id"}, "custom_values": {"description": "Client custom field values", "items": {"$ref": "#/components/schemas/AnomalyCustomValueOutput"}, "title": "Custom Values", "type": "array"}, "distance_to_root": {"description": "Distance to root", "title": "Distance To Root", "type": "number"}, "max_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Max distance", "title": "Max Distance"}, "distance_to_leading_edge": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Distance to leading edge", "title": "Distance To Leading Edge"}, "cross_section_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Cross section distance", "title": "Cross Section Distance"}, "cross_section_chamber_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Cross section chamber distance", "title": "Cross Section Chamber Distance"}, "width": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width", "title": "Width"}, "profile_depth_from": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Profile depth from", "title": "Profile Depth From"}, "profile_depth_to": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Profile depth to", "title": "Profile Depth To"}, "severity": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Severity level", "title": "Severity"}, "status": {"description": "Status", "title": "Status", "type": "string"}, "stage": {"description": "Stage", "title": "Stage", "type": "string"}, "resolution_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resolution status (derived from stage)", "title": "Resolution Status"}, "internal_external": {"description": "Internal/External classification", "title": "Internal External", "type": "string"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Side classification", "title": "Side"}, "cross_section_side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cross section side", "title": "Cross Section Side"}, "cross_section_type": {"description": "Cross section type", "title": "Cross Section Type", "type": "string"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Rib classification", "title": "Rib"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly type ID", "title": "Anomaly Type Id"}, "anomaly_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly type name", "title": "Anomaly Type Name"}, "anomaly_sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly sub-type ID", "title": "Anomaly Sub Type Id"}, "anomaly_sub_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly sub-type name", "title": "Anomaly Sub Type Name"}, "anomaly_major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Major component ID", "title": "Anomaly Major Component Id"}, "anomaly_major_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Major component name", "title": "Anomaly Major Component Name"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component ID", "title": "Anomaly Component Id"}, "anomaly_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component name", "title": "Anomaly Component Name"}, "anomaly_sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sub-component ID", "title": "Anomaly Sub Component Id"}, "anomaly_sub_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sub-component name", "title": "Anomaly Sub Component Name"}, "anomaly_material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Material ID", "title": "Anomaly Material Id"}, "anomaly_material_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly material name", "title": "Anomaly Material Name"}, "parent_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent type ID", "title": "Parent Type Id"}, "root_cause_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Root cause ID", "title": "Root Cause Id"}, "root_cause_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Root cause name", "title": "Root Cause Name"}, "main_image_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "URL of anomaly main image proxy endpoint", "title": "Main Image Url"}, "client_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Client status", "title": "Client Status"}, "chargeable": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the anomaly is chargeable", "title": "Chargeable"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly description", "title": "Description"}, "comments": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comments"}, "service_provider_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service provider ID", "title": "Service Provider Id"}, "damage_cause": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage cause", "title": "Damage Cause"}, "parent_anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "deprecated": true, "description": "Deprecated: No longer used. Use link_group instead.", "title": "Parent Anomaly Id"}, "cross_file_ids": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Cross file IDs as JSON", "title": "Cross File Ids"}, "video_timestamp_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Video timestamp in milliseconds", "title": "Video Timestamp Ms"}, "link_group": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Link group", "title": "Link Group"}, "registered_by": {"description": "Registered by", "title": "Registered By", "type": "string"}, "registered_by_user": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email/username of user who registered anomaly", "title": "Registered By User"}, "registration_origin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration origin", "title": "Registration Origin"}, "width_difference_since_previous": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width difference since previous", "title": "Width Difference Since Previous"}, "width_difference_since_oldest": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width difference since oldest", "title": "Width Difference Since Oldest"}, "length_difference_since_previous": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Length difference since previous", "title": "Length Difference Since Previous"}, "length_difference_since_oldest": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Length difference since oldest", "title": "Length Difference Since Oldest"}, "source_object_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of inspection file from which this anomaly is created from", "title": "Source Object Id"}, "source_object_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Type of source object (e.g., 'inspection_file')", "title": "Source Object Type Id"}, "video_frame": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Video frame number where this anomaly is located", "title": "Video Frame"}, "qr_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Data extracted from QR code if applicable", "title": "Qr Code"}, "segmentation": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Segmentation data as JSON (e.g., polygon coordinates)", "title": "Segmentation"}, "segmentation_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version of the segmentation data format", "title": "Segmentation Version"}, "unity_details": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional details from Unity analysis as JSON", "title": "Unity Details"}, "bbox": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bounding box as JSON string", "title": "Bbox"}, "ai_anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of associated AI-detected anomaly if applicable", "title": "Ai Anomaly Id"}, "ai_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status of AI detection", "title": "Ai Status"}, "ai_confidence": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Confidence score from AI detection", "title": "Ai Confidence"}, "ai_images_v2": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the AI anomaly was imported from the JSON image reference format", "title": "Ai Images V2"}, "frame_blob_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "GCS path to the raw uncropped video frame this anomaly was detected in", "title": "Frame Blob Path"}}, "required": ["updated_at", "id", "distance_to_root", "status", "stage", "internal_external", "cross_section_type", "registered_by"], "title": "AnomalyResponse", "type": "object"}, "AnomalyCreate": {"additionalProperties": false, "description": "Schema for creating Anomaly.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly name", "title": "Name"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "turbine_component_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component serial number", "title": "Turbine Component Serial Number"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Work order ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID", "title": "Service Order Line Id"}, "custom_values": {"anyOf": [{"items": {"$ref": "#/components/schemas/AnomalyCustomValueInput"}, "type": "array"}, {"type": "null"}], "description": "Client custom field values to set on the anomaly", "title": "Custom Values"}, "distance_to_root": {"description": "Distance to root", "title": "Distance To Root", "type": "number"}, "max_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Max distance", "title": "Max Distance"}, "distance_to_leading_edge": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Distance to leading edge", "title": "Distance To Leading Edge"}, "cross_section_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Cross section distance", "title": "Cross Section Distance"}, "cross_section_chamber_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Cross section chamber distance", "title": "Cross Section Chamber Distance"}, "width": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width", "title": "Width"}, "profile_depth_from": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Profile depth from", "title": "Profile Depth From"}, "profile_depth_to": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Profile depth to", "title": "Profile Depth To"}, "severity": {"anyOf": [{"enum": ["LEVEL_0", "LEVEL_1", "LEVEL_2", "LEVEL_3", "LEVEL_4", "LEVEL_5"], "type": "string"}, {"type": "null"}], "description": "Severity level", "title": "Severity"}, "status": {"default": "NEW", "description": "Status", "title": "Status", "type": "string"}, "stage": {"default": "RELEASED", "description": "Stage", "title": "Stage", "type": "string"}, "internal_external": {"description": "Internal/External classification", "title": "Internal External", "type": "string"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Side classification", "title": "Side"}, "cross_section_side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cross section side", "title": "Cross Section Side"}, "cross_section_type": {"default": "DOUBLE_SHEAR_WEB", "description": "Cross section type", "title": "Cross Section Type", "type": "string"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Rib classification", "title": "Rib"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly type ID", "title": "Anomaly Type Id"}, "anomaly_sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly sub-type ID", "title": "Anomaly Sub Type Id"}, "anomaly_major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Major component ID", "title": "Anomaly Major Component Id"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component ID", "title": "Anomaly Component Id"}, "anomaly_sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sub-component ID", "title": "Anomaly Sub Component Id"}, "anomaly_material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Material ID", "title": "Anomaly Material Id"}, "parent_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent type ID", "title": "Parent Type Id"}, "root_cause_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Root cause ID", "title": "Root Cause Id"}, "client_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Client status", "title": "Client Status"}, "chargeable": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the anomaly is chargeable", "title": "Chargeable"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly description", "title": "Description"}, "comments": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comments"}, "service_provider_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service provider ID", "title": "Service Provider Id"}, "damage_cause": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage cause", "title": "Damage Cause"}, "parent_anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "deprecated": true, "description": "Deprecated: No longer used. Use link_group instead.", "title": "Parent Anomaly Id"}, "cross_file_ids": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Cross file IDs as JSON", "title": "Cross File Ids"}, "video_timestamp_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Video timestamp in milliseconds", "title": "Video Timestamp Ms"}, "frame_blob_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "GCS path to the raw uncropped video frame this anomaly was detected in", "title": "Frame Blob Path"}, "link_group": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Link group", "title": "Link Group"}, "registered_by": {"default": "AERONES", "description": "Registered by", "title": "Registered By", "type": "string"}, "registration_origin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration origin", "title": "Registration Origin"}, "width_difference_since_previous": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width difference since previous", "title": "Width Difference Since Previous"}, "width_difference_since_oldest": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width difference since oldest", "title": "Width Difference Since Oldest"}, "length_difference_since_previous": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Length difference since previous", "title": "Length Difference Since Previous"}, "length_difference_since_oldest": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Length difference since oldest", "title": "Length Difference Since Oldest"}, "source_object": {"anyOf": [{}, {"type": "null"}], "description": "Inspection data file reference", "title": "Source Object"}, "video_frame": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Video frame number where this anomaly is located", "title": "Video Frame"}, "segmentation": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Segmentation data as JSON (e.g., polygon coordinates)", "title": "Segmentation"}, "segmentation_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version of the segmentation data format (defaults to 2 when omitted)", "title": "Segmentation Version"}, "bbox": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bounding box as JSON string", "title": "Bbox"}, "ai_status": {"anyOf": [{"enum": ["NEW", "QUALIFIED", "UNQUALIFIED", "CONFIRMED", "REJECTED", "DUPLICATE"], "type": "string"}, {"type": "null"}], "description": "Status of AI detection", "title": "Ai Status"}, "ai_confidence": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Confidence score from AI detection", "title": "Ai Confidence"}, "ai_images_v2": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the AI anomaly was imported from the JSON image reference format", "title": "Ai Images V2"}}, "required": ["distance_to_root", "internal_external"], "title": "AnomalyCreate", "type": "object"}, "AnomalyCustomValueInput": {"additionalProperties": false, "description": "Schema for setting one custom field value on an anomaly.", "properties": {"custom_field_id": {"description": "Customer custom field ID", "title": "Custom Field Id", "type": "integer"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Value for the field. Null or empty clears it.", "title": "Value"}}, "required": ["custom_field_id"], "title": "AnomalyCustomValueInput", "type": "object"}, "AnomalyUpdate": {"additionalProperties": false, "description": "Schema for updating Anomaly.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly name", "title": "Name"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "turbine_component_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component serial number", "title": "Turbine Component Serial Number"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Work order ID", "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID", "title": "Service Order Line Id"}, "custom_values": {"anyOf": [{"items": {"$ref": "#/components/schemas/AnomalyCustomValueInput"}, "type": "array"}, {"type": "null"}], "description": "Client custom field values (replaces the full set)", "title": "Custom Values"}, "distance_to_root": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Distance to root", "title": "Distance To Root"}, "max_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Max distance", "title": "Max Distance"}, "distance_to_leading_edge": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Distance to leading edge", "title": "Distance To Leading Edge"}, "cross_section_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Cross section distance", "title": "Cross Section Distance"}, "cross_section_chamber_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Cross section chamber distance", "title": "Cross Section Chamber Distance"}, "width": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width", "title": "Width"}, "profile_depth_from": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Profile depth from", "title": "Profile Depth From"}, "profile_depth_to": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Profile depth to", "title": "Profile Depth To"}, "severity": {"description": "Severity level", "enum": ["LEVEL_0", "LEVEL_1", "LEVEL_2", "LEVEL_3", "LEVEL_4", "LEVEL_5"], "title": "Severity", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status", "title": "Status"}, "stage": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Stage", "title": "Stage"}, "internal_external": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Internal/External classification", "title": "Internal External"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Side classification", "title": "Side"}, "cross_section_side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cross section side", "title": "Cross Section Side"}, "cross_section_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cross section type", "title": "Cross Section Type"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Rib classification", "title": "Rib"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly type ID", "title": "Anomaly Type Id"}, "anomaly_sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Anomaly sub-type ID", "title": "Anomaly Sub Type Id"}, "anomaly_major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Major component ID", "title": "Anomaly Major Component Id"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component ID", "title": "Anomaly Component Id"}, "anomaly_sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sub-component ID", "title": "Anomaly Sub Component Id"}, "anomaly_material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Material ID", "title": "Anomaly Material Id"}, "parent_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent type ID", "title": "Parent Type Id"}, "root_cause_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Root cause ID", "title": "Root Cause Id"}, "client_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Client status", "title": "Client Status"}, "chargeable": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the anomaly is chargeable", "title": "Chargeable"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Anomaly description", "title": "Description"}, "comments": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comments"}, "service_provider_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service provider ID", "title": "Service Provider Id"}, "damage_cause": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage cause", "title": "Damage Cause"}, "parent_anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "deprecated": true, "description": "Deprecated: No longer used. Use link_group instead.", "title": "Parent Anomaly Id"}, "cross_file_ids": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Cross file IDs as JSON", "title": "Cross File Ids"}, "video_timestamp_ms": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Video timestamp in milliseconds", "title": "Video Timestamp Ms"}, "frame_blob_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "GCS path to the raw uncropped video frame this anomaly was detected in", "title": "Frame Blob Path"}, "link_group": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Link group", "title": "Link Group"}, "registered_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registered by", "title": "Registered By"}, "registration_origin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Registration origin", "title": "Registration Origin"}, "width_difference_since_previous": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width difference since previous", "title": "Width Difference Since Previous"}, "width_difference_since_oldest": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Width difference since oldest", "title": "Width Difference Since Oldest"}, "length_difference_since_previous": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Length difference since previous", "title": "Length Difference Since Previous"}, "length_difference_since_oldest": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Length difference since oldest", "title": "Length Difference Since Oldest"}, "video_frame": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Video frame number where this anomaly is located", "title": "Video Frame"}, "segmentation": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Segmentation data as JSON (e.g., polygon coordinates)", "title": "Segmentation"}, "segmentation_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version of the segmentation data format (null not allowed)", "title": "Segmentation Version"}, "bbox": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Bounding box as JSON string", "title": "Bbox"}, "ai_status": {"anyOf": [{"enum": ["NEW", "QUALIFIED", "UNQUALIFIED", "CONFIRMED", "REJECTED", "DUPLICATE"], "type": "string"}, {"type": "null"}], "description": "Status of AI detection", "title": "Ai Status"}, "ai_confidence": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Confidence score from AI detection", "title": "Ai Confidence"}, "ai_images_v2": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the AI anomaly was imported from the JSON image reference format", "title": "Ai Images V2"}}, "title": "AnomalyUpdate", "type": "object"}, "BladeDiagramAnomaly": {"additionalProperties": false, "description": "Single anomaly data point for blade diagram rendering.", "properties": {"distance_to_root": {"description": "Distance to root in meters", "title": "Distance To Root", "type": "number"}, "severity": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Severity level (LEVEL_1..LEVEL_5, NO_LEVEL, LEVEL_0)", "title": "Severity"}, "internal_external": {"default": "EXTERNAL", "description": "INTERNAL or EXTERNAL \u2014 determines circle fill and stacking direction", "enum": ["INTERNAL", "EXTERNAL"], "title": "Internal External", "type": "string"}}, "required": ["distance_to_root"], "title": "BladeDiagramAnomaly", "type": "object"}, "BladeDiagramRequest": {"additionalProperties": false, "description": "Request body for blade diagram image generation.", "properties": {"blade_length": {"description": "Maximum blade length in meters", "exclusiveMinimum": 0.0, "title": "Blade Length", "type": "number"}, "anomalies": {"description": "Anomalies to plot on the diagram", "items": {"$ref": "#/components/schemas/BladeDiagramAnomaly"}, "title": "Anomalies", "type": "array"}}, "required": ["blade_length", "anomalies"], "title": "BladeDiagramRequest", "type": "object"}, "CrossSectionRequest": {"additionalProperties": false, "description": "Request body for cross-section image generation (single anomaly).", "properties": {"cross_section_type": {"description": "Shear web configuration", "enum": ["NO_SHEAR_WEB", "SINGLE_SHEAR_WEB", "DOUBLE_SHEAR_WEB", "TRIPLE_SHEAR_WEB", "QUADRUPLE_SHEAR_WEB"], "title": "Cross Section Type", "type": "string"}, "cross_section_side": {"description": "Structural element for marker placement", "enum": ["SUCTION_SIDE", "PRESSURE_SIDE", "MSW1", "MSW2", "TE_WEB", "END_WEB", "BEAM_LE", "BEAM_TE", "BEAM_PS", "BEAM_SS"], "title": "Cross Section Side", "type": "string"}, "severity": {"description": "Severity level (determines marker colour)", "enum": ["LEVEL_0", "LEVEL_1", "LEVEL_2", "LEVEL_3", "LEVEL_4", "LEVEL_5", "NO_LEVEL"], "title": "Severity", "type": "string"}, "internal_external": {"description": "Damage classification (INTERNAL renders outline-only marker)", "enum": ["INTERNAL", "EXTERNAL", "BOTH"], "title": "Internal External", "type": "string"}, "cross_section_distance": {"anyOf": [{"maximum": 1.0, "minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Absolute position (0-1) along the curve or line", "title": "Cross Section Distance"}, "cross_section_chamber_distance": {"anyOf": [{"maximum": 1.0, "minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Chamber-relative position (0-1) within the rib sector. Takes priority over cross_section_distance when set. Converted to absolute using rib sector boundaries for INTERNAL anomalies on curve sides.", "title": "Cross Section Chamber Distance"}, "side": {"anyOf": [{"enum": ["PRESSURE_SIDE", "SUCTION_SIDE", "LEADING_EDGE", "TRAILING_EDGE"], "type": "string"}, {"type": "null"}], "description": "Blade side (defaults to PRESSURE_SIDE for INTERNAL anomalies)", "title": "Side"}, "rib": {"anyOf": [{"enum": ["LEADING_EDGE", "CENTER", "MID_1", "MID_2", "MID_3", "TRAILING_EDGE"], "type": "string"}, {"type": "null"}], "description": "Rib/chamber (used for chamber distance conversion on INTERNAL)", "title": "Rib"}}, "required": ["cross_section_type", "cross_section_side", "severity", "internal_external"], "title": "CrossSectionRequest", "type": "object"}, "TimezoneQueryParams": {"additionalProperties": false, "description": "Query parameters for timezones endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by city (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "TimezoneQueryParams", "type": "object"}, "TimezoneResponse": {"additionalProperties": false, "description": "Schema for Timezone response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Timezone ID", "title": "Id", "type": "integer"}, "city": {"description": "City name", "title": "City", "type": "string"}, "timezone": {"description": "Timezone identifier", "title": "Timezone", "type": "string"}, "abbrev": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Timezone abbreviation", "title": "Abbrev"}, "utc_offset": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "UTC offset", "title": "Utc Offset"}, "is_dst": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is daylight saving time", "title": "Is Dst"}, "region_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Region name", "title": "Region Name"}}, "required": ["updated_at", "id", "city", "timezone"], "title": "TimezoneResponse", "type": "object"}, "CurrencyQueryParams": {"additionalProperties": false, "description": "Query parameters for currencies endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "CurrencyQueryParams", "type": "object"}, "CurrencyResponse": {"additionalProperties": false, "description": "Schema for Currency response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Currency ID", "title": "Id", "type": "integer"}, "code": {"description": "ISO 4217 currency code", "title": "Code", "type": "string"}, "name": {"description": "Currency name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "code", "name"], "title": "CurrencyResponse", "type": "object"}, "BusinessRegionQueryParams": {"additionalProperties": false, "description": "Query parameters for business regions endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "BusinessRegionQueryParams", "type": "object"}, "BusinessRegionResponse": {"additionalProperties": false, "description": "Schema for Business Region response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Business region ID", "title": "Id", "type": "integer"}, "name": {"description": "Business region name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "name"], "title": "BusinessRegionResponse", "type": "object"}, "RegionQueryParams": {"additionalProperties": false, "description": "Query parameters for regions endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "RegionQueryParams", "type": "object"}, "RegionResponse": {"additionalProperties": false, "description": "Schema for Region response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Region ID", "title": "Id", "type": "integer"}, "name": {"description": "Region name", "title": "Name", "type": "string"}}, "required": ["updated_at", "id", "name"], "title": "RegionResponse", "type": "object"}, "TermsOfServiceQueryParams": {"additionalProperties": false, "description": "Query parameters for Terms of Service endpoint.", "properties": {"is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by active status", "title": "Is Active"}, "is_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by required status", "title": "Is Required"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by title, version, or content", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "TermsOfServiceQueryParams", "type": "object"}, "TermsOfServiceResponse": {"additionalProperties": false, "description": "Schema for Terms of Service response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Terms of Service ID", "title": "Id", "type": "integer"}, "version": {"description": "Version identifier", "title": "Version", "type": "string"}, "title": {"description": "Terms of Service title", "title": "Title", "type": "string"}, "content": {"description": "Terms of Service content", "title": "Content", "type": "string"}, "is_required": {"description": "Whether acceptance is required", "title": "Is Required", "type": "boolean"}, "is_active": {"description": "Whether this version is active", "title": "Is Active", "type": "boolean"}}, "required": ["updated_at", "id", "version", "title", "content", "is_required", "is_active"], "title": "TermsOfServiceResponse", "type": "object"}, "UserTosAcceptanceQueryParams": {"additionalProperties": false, "description": "Query parameters for User ToS Acceptance endpoint.", "properties": {"user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by user ID", "title": "User Id"}, "tos_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by ToS ID", "title": "Tos Id"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "UserTosAcceptanceQueryParams", "type": "object"}, "UserTosAcceptanceResponse": {"additionalProperties": false, "description": "Schema for User ToS Acceptance response.\n\nNote: This is an immutable record, so only created_at is included (no updated_at).", "properties": {"id": {"description": "User ToS Acceptance ID", "title": "Id", "type": "integer"}, "user_id": {"description": "User ID", "title": "User Id", "type": "integer"}, "tos_id": {"description": "Terms of Service ID", "title": "Tos Id", "type": "integer"}, "ip_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User IP address", "title": "Ip Address"}, "user_agent": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User agent string", "title": "User Agent"}, "created_at": {"description": "Acceptance timestamp", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "user_id", "tos_id", "created_at"], "title": "UserTosAcceptanceResponse", "type": "object"}, "UserTosAcceptanceCreate": {"additionalProperties": false, "description": "Schema for creating a User ToS Acceptance.", "properties": {"tos_id": {"description": "Terms of Service ID", "title": "Tos Id", "type": "integer"}, "ip_address": {"anyOf": [{"maxLength": 45, "type": "string"}, {"type": "null"}], "description": "User IP address", "title": "Ip Address"}, "user_agent": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User agent string", "title": "User Agent"}}, "required": ["tos_id"], "title": "UserTosAcceptanceCreate", "type": "object"}, "DailyReportDownloadRequest": {"additionalProperties": false, "description": "Request body for generating a daily report from the client portal.", "properties": {"service_order_line_id": {"description": "Service order line ID to generate the report for", "title": "Service Order Line Id", "type": "integer"}, "date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Optional report date (YYYY-MM-DD). If omitted, the report covers all activity dates for the SOL.", "title": "Date"}}, "required": ["service_order_line_id"], "title": "DailyReportDownloadRequest", "type": "object"}, "FinalReportDownloadRequest": {"additionalProperties": false, "description": "Request body for generating a final (SOL) report from the client portal.", "properties": {"service_order_line_id": {"description": "Service order line ID to generate the final report for", "title": "Service Order Line Id", "type": "integer"}}, "required": ["service_order_line_id"], "title": "FinalReportDownloadRequest", "type": "object"}, "FinalReportStartResponse": {"additionalProperties": false, "description": "Response after kicking off async final-report generation.", "properties": {"generation_id": {"description": "Report row ID", "title": "Generation Id", "type": "integer"}, "status": {"description": "pending | complete | failed", "title": "Status", "type": "string"}}, "required": ["generation_id", "status"], "title": "FinalReportStartResponse", "type": "object"}, "CustomReportRequest": {"additionalProperties": false, "description": "Request body for a custom report: the family and the selection (Ops Hub ids).", "properties": {"report_type": {"description": "Report family, e.g. 'findings'", "title": "Report Type", "type": "string"}, "turbine_ids": {"items": {"type": "integer"}, "title": "Turbine Ids", "type": "array"}, "location_ids": {"items": {"type": "integer"}, "title": "Location Ids", "type": "array"}, "project_ids": {"items": {"type": "integer"}, "title": "Project Ids", "type": "array"}, "date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Earliest inspection completion date (inclusive)", "title": "Date From"}, "date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Latest inspection completion date (inclusive)", "title": "Date To"}, "severity_levels": {"description": "Severity band, LEVEL_0 .. LEVEL_5", "items": {"type": "string"}, "title": "Severity Levels", "type": "array"}, "anomaly_type_ids": {"items": {"type": "integer"}, "title": "Anomaly Type Ids", "type": "array"}, "services": {"description": "Service codes of the family, e.g. IIN / VIN; empty means all", "items": {"type": "string"}, "title": "Services", "type": "array"}}, "required": ["report_type"], "title": "CustomReportRequest", "type": "object"}, "CustomReportListQueryParams": {"additionalProperties": false, "description": "Query parameters for the custom report list.", "properties": {"limit": {"default": 20, "description": "Newest requests to return", "maximum": 100, "minimum": 1, "title": "Limit", "type": "integer"}}, "title": "CustomReportListQueryParams", "type": "object"}, "CustomReportSummary": {"additionalProperties": false, "description": "One custom report request as the portal lists it.", "properties": {"generation_id": {"title": "Generation Id", "type": "integer"}, "report_type": {"title": "Report Type", "type": "string"}, "status": {"description": "pending | complete | failed", "title": "Status", "type": "string"}, "selection": {"title": "Selection", "type": "object"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "generated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Generated At"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}}, "required": ["generation_id", "report_type", "status", "selection"], "title": "CustomReportSummary", "type": "object"}, "CustomReportService": {"additionalProperties": false, "description": "One \"Service\" choice of a family: the service code and the label the portal shows.", "properties": {"code": {"title": "Code", "type": "string"}, "label": {"title": "Label", "type": "string"}}, "required": ["code", "label"], "title": "CustomReportService", "type": "object"}, "CustomReportType": {"additionalProperties": false, "description": "One report family the portal may request, with the request fields it reads, its services and its cap.", "properties": {"name": {"title": "Name", "type": "string"}, "label": {"title": "Label", "type": "string"}, "filters": {"description": "CustomReportRequest fields the family reads", "items": {"type": "string"}, "title": "Filters", "type": "array"}, "services": {"items": {"$ref": "#/components/schemas/CustomReportService"}, "title": "Services", "type": "array"}, "max_selection_lines": {"title": "Max Selection Lines", "type": "integer"}}, "required": ["name", "label", "filters", "services", "max_selection_lines"], "title": "CustomReportType", "type": "object"}, "FinalReportStatusResponse": {"additionalProperties": false, "description": "Polling response for an in-flight final-report generation.", "properties": {"generation_id": {"title": "Generation Id", "type": "integer"}, "status": {"description": "pending | complete | failed", "title": "Status", "type": "string"}, "generated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Generated At"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}}, "required": ["generation_id", "status"], "title": "FinalReportStatusResponse", "type": "object"}, "ProjectQuestionConfigQueryParams": {"additionalProperties": false, "description": "Query parameters for project question configs endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by title", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "section": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by section", "title": "Section"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code (e.g. IIN-ONS)", "title": "Service Code"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}}, "title": "ProjectQuestionConfigQueryParams", "type": "object"}, "ProjectQuestionConfigResponse": {"additionalProperties": false, "description": "Schema for ProjectQuestionConfig response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "section": {"title": "Section", "type": "string"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceObject"}, {"type": "null"}]}, "priority": {"title": "Priority", "type": "integer"}, "key": {"title": "Key", "type": "string"}, "title": {"title": "Title", "type": "string"}, "type": {"title": "Type", "type": "string"}, "required": {"title": "Required", "type": "boolean"}, "choices": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Choices"}, "tooltip": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Tooltip"}, "unit": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Unit"}, "enabled": {"title": "Enabled", "type": "boolean"}}, "required": ["updated_at", "id", "section", "priority", "key", "title", "type", "required", "enabled"], "title": "ProjectQuestionConfigResponse", "type": "object"}, "ProjectStatusQueryParams": {"additionalProperties": false, "description": "Query parameters for project status endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by code (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by enabled status", "title": "Enabled"}}, "title": "ProjectStatusQueryParams", "type": "object"}, "ProjectStatusResponse": {"additionalProperties": false, "description": "Schema for ProjectStatus response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project status ID", "title": "Id", "type": "integer"}, "code": {"description": "Status code", "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status description", "title": "Description"}, "enabled": {"description": "Whether status is enabled", "title": "Enabled", "type": "boolean"}, "sort_order": {"description": "Sort order for display", "title": "Sort Order", "type": "integer"}}, "required": ["updated_at", "id", "code", "enabled", "sort_order"], "title": "ProjectStatusResponse", "type": "object"}, "ReportTypeQueryParams": {"additionalProperties": false, "description": "Query params for the ReportType readonly list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Enabled"}}, "title": "ReportTypeQueryParams", "type": "object"}, "ReportTypeResponse": {"additionalProperties": false, "description": "Schema for ReportType response (readonly lookup).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Report type ID", "title": "Id", "type": "integer"}, "code": {"description": "Stable report type code", "title": "Code", "type": "string"}, "name": {"description": "Human-readable report type name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Report type description", "title": "Description"}, "enabled": {"description": "Whether the report type is selectable", "title": "Enabled", "type": "boolean"}, "sort_order": {"description": "Display order", "title": "Sort Order", "type": "integer"}}, "required": ["updated_at", "id", "code", "name", "enabled", "sort_order"], "title": "ReportTypeResponse", "type": "object"}, "PipedriveDealQueryParams": {"additionalProperties": false, "description": "Query parameters for pipedrive-deals endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by title (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "PipedriveDealQueryParams", "type": "object"}, "PipedriveDealResponse": {"additionalProperties": false, "description": "Schema for PipedriveDeal response.\n\nReturns parsed title (project code only, e.g., 'EDFR-5308' from 'EDFR-5308 IIN x6').\nDeals without a valid title/project code are filtered out.", "properties": {"updated_at": {"description": "Last update timestamp from Pipedrive", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Pipedrive deal ID", "title": "Id", "type": "string"}, "title": {"description": "Parsed deal title (project code only)", "title": "Title", "type": "string"}}, "required": ["updated_at", "id", "title"], "title": "PipedriveDealResponse", "type": "object"}, "ProjectPreJobAnswerResponse": {"additionalProperties": false, "description": "Schema for ProjectPreJobAnswer response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "project_id": {"title": "Project Id", "type": "integer"}, "question_id": {"title": "Question Id", "type": "integer"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceObject"}, {"type": "null"}]}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "title": {"title": "Title", "type": "string"}, "answer": {"title": "Answer"}}, "required": ["updated_at", "id", "project_id", "question_id", "title", "answer"], "title": "ProjectPreJobAnswerResponse", "type": "object"}, "ProjectPreJobAnswerBulkItem": {"additionalProperties": false, "description": "Single item in a bulk update request \u2014 answer ID + fields to update.", "properties": {"id": {"description": "Answer ID to update", "title": "Id", "type": "integer"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Question title snapshot", "title": "Title"}, "answer": {"anyOf": [{}, {"type": "null"}], "description": "Answer value (any valid JSON)", "title": "Answer"}}, "required": ["id"], "title": "ProjectPreJobAnswerBulkItem", "type": "object"}, "ProjectPreJobAnswerBulkUpdate": {"additionalProperties": false, "description": "Schema for bulk-updating pre-job answers.", "properties": {"items": {"description": "List of answers to update", "items": {"$ref": "#/components/schemas/ProjectPreJobAnswerBulkItem"}, "minItems": 1, "title": "Items", "type": "array"}}, "required": ["items"], "title": "ProjectPreJobAnswerBulkUpdate", "type": "object"}, "ProjectPreJobAnswerCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectPreJobAnswer.", "properties": {"question_id": {"description": "Question config ID", "title": "Question Id", "type": "integer"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "title": {"description": "Question title snapshot", "title": "Title", "type": "string"}, "answer": {"description": "Answer value (any valid JSON)", "title": "Answer"}}, "required": ["question_id", "title", "answer"], "title": "ProjectPreJobAnswerCreate", "type": "object"}, "ProjectPreJobAnswerUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectPreJobAnswer.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Question title snapshot", "title": "Title"}, "answer": {"anyOf": [{}, {"type": "null"}], "description": "Answer value (any valid JSON)", "title": "Answer"}}, "title": "ProjectPreJobAnswerUpdate", "type": "object"}, "ProjectBillingResponse": {"additionalProperties": false, "description": "Schema for ProjectBilling response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project billing ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "billing_lead": {"anyOf": [{"$ref": "#/components/schemas/ProjectContactObject"}, {"type": "null"}], "description": "Project contact acting as billing lead"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing address", "title": "Address"}, "address_state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing address state", "title": "Address State"}, "invoice_recipient": {"anyOf": [{"$ref": "#/components/schemas/CustomerObject"}, {"type": "null"}], "description": "Customer receiving the invoice"}, "payment_terms_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text comment for payment terms", "title": "Payment Terms Comment"}, "payment_terms": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Payment terms code", "title": "Payment Terms"}, "purchase_order_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether a purchase order is required", "title": "Purchase Order Required"}, "purchase_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Purchase order number", "title": "Purchase Order Number"}, "purchase_order_value": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Purchase order value", "title": "Purchase Order Value"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency"}, "invoicing_method": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing method", "title": "Invoicing Method"}, "invoicing_instructions": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing instructions", "title": "Invoicing Instructions"}, "invoicing_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing email(s)", "title": "Invoicing Email"}, "additional_invoice_approval_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether an additional invoice approval is required", "title": "Additional Invoice Approval Required"}, "invoice_approver_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice approver full name", "title": "Invoice Approver Full Name"}, "invoice_approver_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice approver email", "title": "Invoice Approver Email"}, "invoice_frequency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice frequency", "title": "Invoice Frequency"}, "sales_tax_exemption_certificate": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether a sales tax exemption certificate applies", "title": "Sales Tax Exemption Certificate"}, "sales_tax_exemption_certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales tax exemption certificate number", "title": "Sales Tax Exemption Certificate Number"}, "receive_daily_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Would you like to receive daily reports?'", "title": "Receive Daily Reports"}, "specific_report_requirements": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Specific report requirements?'", "title": "Specific Report Requirements"}, "receive_draft_charge_statements": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Do you want to receive draft charge statements?'", "title": "Receive Draft Charge Statements"}, "draft_charge_statement_frequency": {"anyOf": [{"enum": ["WEEKLY", "MONTHLY"], "type": "string"}, {"type": "null"}], "description": "Draft charge statement delivery frequency", "title": "Draft Charge Statement Frequency"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/VendorObject"}, {"type": "null"}], "description": "Vendor"}}, "required": ["updated_at", "id", "project_id"], "title": "ProjectBillingResponse", "type": "object"}, "ProjectContactObject": {"additionalProperties": false, "description": "Nested project contact object for Project response (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "role": {"anyOf": [{"$ref": "#/components/schemas/ProjectContactRole"}, {"type": "null"}]}, "customer_contact_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Contact Name"}, "customer_type": {"title": "Customer Type", "type": "string"}}, "required": ["id", "customer_type"], "title": "ProjectContactObject", "type": "object"}, "ProjectContactRole": {"description": "All possible roles for ProjectContact (used in responses).\n\nNote: The backend historically uses the typo'd value REPORT_RECEPIENT and we\nintentionally preserve it for API compatibility.", "enum": ["PRIMARY_CONTACT", "REPORT_RECEPIENT", "INVOICE_APPROVER", "SITE_CONTACT", "QHSE_CONTACT"], "title": "ProjectContactRole", "type": "string"}, "PurchaseOrderCustomerRef": {"additionalProperties": false, "description": "Slim customer reference for PurchaseOrder responses.\n\nIntentionally does not nest the customer's own currency \u2014 a PO carries\nits own currency, independent of the customer's default.", "properties": {"id": {"title": "Id", "type": "integer"}, "display_name": {"title": "Display Name", "type": "string"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}}, "required": ["id", "display_name"], "title": "PurchaseOrderCustomerRef", "type": "object"}, "PurchaseOrderResponse": {"additionalProperties": false, "description": "PurchaseOrder with its current version inlined for list/detail use.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PurchaseOrderCustomerRef"}, {"type": "null"}]}, "currency": {"anyOf": [{"$ref": "#/components/schemas/CurrencyObject"}, {"type": "null"}]}, "current_version": {"anyOf": [{"$ref": "#/components/schemas/PurchaseOrderVersionObject"}, {"type": "null"}]}, "project_ids": {"items": {"type": "integer"}, "title": "Project Ids", "type": "array"}}, "required": ["updated_at", "id"], "title": "PurchaseOrderResponse", "type": "object"}, "PurchaseOrderVersionObject": {"additionalProperties": false, "description": "Nested purchase order version object (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "version_number": {"title": "Version Number", "type": "integer"}, "order_number": {"title": "Order Number", "type": "string"}, "issue_date": {"format": "date", "title": "Issue Date", "type": "string"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "file_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "File Id"}}, "required": ["id", "version_number", "order_number", "issue_date", "amount"], "title": "PurchaseOrderVersionObject", "type": "object"}, "RfiBillingCompositeResponse": {"additionalProperties": false, "description": "Project billing snapshot plus purchase orders linked for RFI Billing.\n\n``updated_at`` is the canonical ``ProjectBilling`` row timestamp (same row as\n``project_billing``).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "project_id": {"description": "Core project ID", "title": "Project Id", "type": "integer"}, "offer_status": {"description": "Effective offer status: the latest ProjectOffer.status, or 'Draft' when the project has no offer yet. RFI Billing gates currency editing on this (editable only while 'Draft').", "title": "Offer Status", "type": "string"}, "project_billing": {"$ref": "#/components/schemas/ProjectBillingResponse", "description": "Canonical ProjectBilling row for this project"}, "linked_purchase_orders": {"description": "Purchase orders linked via PurchaseOrderProject", "items": {"$ref": "#/components/schemas/PurchaseOrderResponse"}, "title": "Linked Purchase Orders", "type": "array"}}, "required": ["updated_at", "project_id", "offer_status", "project_billing"], "title": "RfiBillingCompositeResponse", "type": "object"}, "VendorObject": {"additionalProperties": false, "description": "Nested vendor object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "display_name": {"title": "Display Name", "type": "string"}}, "required": ["id", "display_name"], "title": "VendorObject", "type": "object"}, "ProjectBillingUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectBilling (partial).", "properties": {"billing_lead_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project contact acting as billing lead", "title": "Billing Lead Id"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing address", "title": "Address"}, "address_state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing address state", "title": "Address State"}, "invoice_recipient_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer receiving the invoice", "title": "Invoice Recipient Id"}, "payment_terms_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text comment for payment terms", "title": "Payment Terms Comment"}, "payment_terms": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Payment terms code", "title": "Payment Terms"}, "purchase_order_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether a purchase order is required", "title": "Purchase Order Required"}, "purchase_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Purchase order number", "title": "Purchase Order Number"}, "purchase_order_value": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Purchase order value", "title": "Purchase Order Value"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency"}, "invoicing_method": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing method", "title": "Invoicing Method"}, "invoicing_instructions": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing instructions", "title": "Invoicing Instructions"}, "invoicing_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing email(s)", "title": "Invoicing Email"}, "additional_invoice_approval_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether an additional invoice approval is required", "title": "Additional Invoice Approval Required"}, "invoice_approver_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice approver full name", "title": "Invoice Approver Full Name"}, "invoice_approver_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice approver email", "title": "Invoice Approver Email"}, "invoice_frequency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice frequency", "title": "Invoice Frequency"}, "sales_tax_exemption_certificate": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether a sales tax exemption certificate applies", "title": "Sales Tax Exemption Certificate"}, "sales_tax_exemption_certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales tax exemption certificate number", "title": "Sales Tax Exemption Certificate Number"}, "receive_daily_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Would you like to receive daily reports?'", "title": "Receive Daily Reports"}, "specific_report_requirements": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Specific report requirements?'", "title": "Specific Report Requirements"}, "receive_draft_charge_statements": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Do you want to receive draft charge statements?'", "title": "Receive Draft Charge Statements"}, "draft_charge_statement_frequency": {"anyOf": [{"enum": ["WEEKLY", "MONTHLY"], "type": "string"}, {"type": "null"}], "description": "Draft charge statement delivery frequency", "title": "Draft Charge Statement Frequency"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Vendor ID", "title": "Vendor Id"}}, "title": "ProjectBillingUpdate", "type": "object"}, "RfiBillingCompositeUpdate": {"additionalProperties": false, "description": "Partial update for the RFI Billing composite (ProjectBilling + linked POs).\n\nUse ``project_billing`` with partial fields per ``exclude_unset`` semantics.\nFor ``linked_purchase_order_ids``: include the field to reconcile junction rows\nto that exact id set (``[]`` clears all links). Omit the field entirely to leave\nexisting links unchanged.", "properties": {"project_billing": {"anyOf": [{"$ref": "#/components/schemas/ProjectBillingUpdate"}, {"type": "null"}], "description": "Partial ProjectBilling fields; omit to skip billing mutation"}, "linked_purchase_order_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Core purchase_order ids linked to this project. Present (even as []) reconciles links; omit to leave links untouched.", "title": "Linked Purchase Order Ids"}}, "title": "RfiBillingCompositeUpdate", "type": "object"}, "PreJobSiteAnswerObject": {"additionalProperties": false, "description": "Pre-job answer within a site response.", "properties": {"id": {"title": "Id", "type": "integer"}, "question_id": {"title": "Question Id", "type": "integer"}, "key": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Question config key for programmatic access", "title": "Key"}, "title": {"title": "Title", "type": "string"}, "answer": {"title": "Answer"}}, "required": ["id", "question_id", "title", "answer"], "title": "PreJobSiteAnswerObject", "type": "object"}, "PreJobSiteContactObject": {"additionalProperties": false, "description": "Contact within a site response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}, "is_qhse": {"default": false, "title": "Is Qhse", "type": "boolean"}}, "required": ["id"], "title": "PreJobSiteContactObject", "type": "object"}, "PreJobSiteFileObject": {"additionalProperties": false, "description": "File link within a site response.", "properties": {"id": {"title": "Id", "type": "integer"}, "file_id": {"title": "File Id", "type": "integer"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Additional Information"}}, "required": ["id", "file_id"], "title": "PreJobSiteFileObject", "type": "object"}, "PreJobSiteLocationObject": {"additionalProperties": false, "description": "Location details within a pre-job site response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Formatted address from address components", "title": "Address"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}]}, "timezone": {"anyOf": [{"$ref": "#/components/schemas/TimezoneObject"}, {"type": "null"}]}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Longitude"}, "custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "certificates": {"description": "Location certificates [{id, name, is_mandatory}]", "items": {"type": "object"}, "title": "Certificates", "type": "array"}}, "required": ["id", "name"], "title": "PreJobSiteLocationObject", "type": "object"}, "PreJobSiteOMBuildingObject": {"additionalProperties": false, "description": "O&M building address in the pre-job sites response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "address_line1": {"title": "Address Line1", "type": "string"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address Line2"}, "city": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Postal Code"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}]}, "timezone": {"anyOf": [{"$ref": "#/components/schemas/TimezoneObject"}, {"type": "null"}]}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Additional Info"}}, "required": ["id", "address_line1"], "title": "PreJobSiteOMBuildingObject", "type": "object"}, "PreJobSiteObject": {"additionalProperties": false, "description": "Single site (project location) in the pre-job sites response.", "properties": {"project_location_id": {"title": "Project Location Id", "type": "integer"}, "location": {"$ref": "#/components/schemas/PreJobSiteLocationObject"}, "contact": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteContactObject"}, {"type": "null"}], "description": "Primary contact from ProjectContact"}, "customer_contacts": {"description": "Contacts linked to the customer-location relationship", "items": {"$ref": "#/components/schemas/PreJobSiteContactObject"}, "title": "Customer Contacts", "type": "array"}, "pre_job_answers": {"items": {"$ref": "#/components/schemas/PreJobSiteAnswerObject"}, "title": "Pre Job Answers", "type": "array"}, "files": {"items": {"$ref": "#/components/schemas/PreJobSiteFileObject"}, "title": "Files", "type": "array"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Additional Information"}, "om_building_address": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteOMBuildingObject"}, {"type": "null"}]}, "required_certifications": {"description": "Per-project required certifications. Primary source is ``CustomerLocation.metadata.required_certifications``; falls back to legacy ``projects.Site.required_certifications`` (matched by site name) when the metadata entry is missing. Consumed by RAMS prefill to populate the qualifications section.", "items": {"type": "string"}, "title": "Required Certifications", "type": "array"}, "other_certification_details": {"default": "", "description": "Free-text certification details. Primary source is ``CustomerLocation.metadata.other_certification_details``; falls back to legacy ``projects.Site.other_certification_details`` when the metadata entry is missing. Consumed by RAMS prefill to populate the qualifications section.", "title": "Other Certification Details", "type": "string"}, "suggested_certifications": {"description": "Certificates auto-assigned to this site by the certificate mapping rules (``core.certificate_requirement_rule``), resolved from the site's region and its scope-item services. Not removable on the pre-job form.", "items": {"$ref": "#/components/schemas/PreJobSuggestedCertificationObject"}, "title": "Suggested Certifications", "type": "array"}}, "required": ["project_location_id", "location"], "title": "PreJobSiteObject", "type": "object"}, "PreJobSitesResponse": {"additionalProperties": false, "description": "Top-level response for the pre-job sites aggregation endpoint.", "properties": {"sites": {"items": {"$ref": "#/components/schemas/PreJobSiteObject"}, "title": "Sites", "type": "array"}, "om_building_address": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteOMBuildingObject"}, {"type": "null"}], "description": "Mirror of the first site's ``om_building_address`` in list order when present; null when that site has no ``ProjectLocation.om_building_customer_address``. Prefer each site object for per-location O&M."}}, "required": ["sites"], "title": "PreJobSitesResponse", "type": "object"}, "PreJobSuggestedCertificationObject": {"additionalProperties": false, "description": "One certificate auto-assigned to a site by the certificate mapping rules.", "properties": {"id": {"description": "Certificate ID", "title": "Id", "type": "integer"}, "name": {"description": "Certificate name", "title": "Name", "type": "string"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Condition note from the matching rule", "title": "Comment"}}, "required": ["id", "name"], "title": "PreJobSuggestedCertificationObject", "type": "object"}, "CustomerContactObject": {"additionalProperties": false, "description": "Nested customer contact object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}}, "required": ["id", "name"], "title": "CustomerContactObject", "type": "object"}, "CustomerLocationObject": {"additionalProperties": false, "description": "Nested customer location object for responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "location": {"$ref": "#/components/schemas/LocationObject"}, "relationship": {"anyOf": [{"$ref": "#/components/schemas/RelationshipTypeObject"}, {"type": "null"}]}}, "required": ["id", "location"], "title": "CustomerLocationObject", "type": "object"}, "ProjectContactResponse": {"additionalProperties": false, "description": "Schema for ProjectContact response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project contact ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "customer_contact": {"$ref": "#/components/schemas/CustomerContactObject", "description": "Customer contact information"}, "role": {"anyOf": [{"$ref": "#/components/schemas/ProjectContactRole"}, {"type": "null"}], "description": "Role in project"}, "customer_type": {"description": "Customer type: 'billing' or 'requesting'", "enum": ["billing", "requesting"], "title": "Customer Type", "type": "string"}, "customer_location": {"anyOf": [{"$ref": "#/components/schemas/CustomerLocationObject"}, {"type": "null"}], "description": "Customer location information"}}, "required": ["updated_at", "id", "project_id", "customer_contact", "customer_type"], "title": "ProjectContactResponse", "type": "object"}, "ProjectContactCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectContact.", "properties": {"customer_contact_id": {"description": "Customer contact ID", "title": "Customer Contact Id", "type": "integer"}, "role": {"anyOf": [{"$ref": "#/components/schemas/ProjectContactMutableRole"}, {"type": "null"}], "description": "Role in project"}, "customer_type": {"description": "Customer type: 'billing' or 'requesting'", "enum": ["billing", "requesting"], "title": "Customer Type", "type": "string"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}}, "required": ["customer_contact_id", "customer_type"], "title": "ProjectContactCreate", "type": "object"}, "ProjectContactMutableRole": {"description": "Roles allowed when creating or updating a ProjectContact.\n\nSITE_CONTACT remains migration-managed and read-only. QHSE_CONTACT is\nassignable through the API for pre-job safety workflows.", "enum": ["PRIMARY_CONTACT", "REPORT_RECEPIENT", "INVOICE_APPROVER", "QHSE_CONTACT"], "title": "ProjectContactMutableRole", "type": "string"}, "ProjectContactUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectContact.", "properties": {"customer_contact_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer contact ID", "title": "Customer Contact Id"}, "role": {"anyOf": [{"$ref": "#/components/schemas/ProjectContactMutableRole"}, {"type": "null"}], "description": "Role in project"}, "customer_type": {"anyOf": [{"enum": ["billing", "requesting"], "type": "string"}, {"type": "null"}], "description": "Customer type: 'billing' or 'requesting'", "title": "Customer Type"}, "customer_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer location ID", "title": "Customer Location Id"}}, "title": "ProjectContactUpdate", "type": "object"}, "LocationObjectExpanded": {"additionalProperties": false, "description": "Expanded location object with full details for ProjectLocation responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Location type (WIND_PARK, etc.)", "title": "Type"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full address (computed from address fields)", "title": "Address"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryObject"}, {"type": "null"}], "description": "Country details"}, "timezone": {"anyOf": [{"$ref": "#/components/schemas/TimezoneObject"}, {"type": "null"}], "description": "Timezone details"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "GPS latitude", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "GPS longitude", "title": "Longitude"}, "certificates": {"description": "Required certificates with id, name, is_mandatory", "items": {"type": "object"}, "title": "Certificates", "type": "array"}}, "required": ["id"], "title": "LocationObjectExpanded", "type": "object"}, "ProjectLocationResponse": {"additionalProperties": false, "description": "Schema for ProjectLocation response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project location ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "location": {"$ref": "#/components/schemas/LocationObjectExpanded", "description": "Expanded location information with full details"}, "project_contact_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project contact ID", "title": "Project Contact Id"}, "om_building_customer_address_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pre-job O&M building: optional FK to ``CustomerAddress`` (``OM_BUILDING``); null when not linked", "title": "Om Building Customer Address Id"}, "contact": {"anyOf": [{"$ref": "#/components/schemas/CustomerContactObject"}, {"type": "null"}], "description": "Customer contact information"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "required": ["updated_at", "id", "project_id", "location"], "title": "ProjectLocationResponse", "type": "object"}, "ProjectLocationBulkCreate": {"additionalProperties": false, "description": "Schema for bulk-creating ProjectLocations.", "properties": {"location_ids": {"description": "List of Location IDs to assign to project", "items": {"type": "integer"}, "minItems": 1, "title": "Location Ids", "type": "array"}}, "required": ["location_ids"], "title": "ProjectLocationBulkCreate", "type": "object"}, "ProjectLocationServicesResponse": {"additionalProperties": false, "description": "Services commercially available at one project location \u2014 the union of\nservices on approved commercial-offer items and project scope items there.\nGeneral-purpose (offer\u222ascope coverage per site); any feature can use it to\nconstrain a (site, service) choice to what the project actually sells.", "properties": {"project_location_id": {"description": "ProjectLocation id", "title": "Project Location Id", "type": "integer"}, "location_id": {"description": "Underlying Location id", "title": "Location Id", "type": "integer"}, "service_ids": {"description": "Ids of services offered (approved offer) or scoped at this site", "items": {"type": "integer"}, "title": "Service Ids", "type": "array"}}, "required": ["project_location_id", "location_id"], "title": "ProjectLocationServicesResponse", "type": "object"}, "PreJobSiteCompositeCustomerLocationObject": {"additionalProperties": false, "description": "CustomerLocation slice returned by the per-location pre-job composite GET.", "properties": {"id": {"description": "Customer location ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "location_id": {"description": "Core location ID", "title": "Location Id", "type": "integer"}, "metadata": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Per customer\u2013location JSON (e.g. access, schedule, certifications flags)", "title": "Metadata"}, "relationship_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Relationship type ID when set", "title": "Relationship Id"}}, "required": ["id", "customer_id", "location_id"], "title": "PreJobSiteCompositeCustomerLocationObject", "type": "object"}, "PreJobSiteCompositeResponse": {"additionalProperties": false, "description": "Full pre-job payload for one project location (GET .../locations/{id}/pre-job).\n\n`location_id` in the route is ProjectLocation.id. Includes the CustomerLocation\nrow when the requesting customer is linked to the underlying Location.\n\n``updated_at`` is the ``ProjectLocation`` row timestamp (same entity as\n``project_location_id``).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "project_location_id": {"title": "Project Location Id", "type": "integer"}, "location": {"$ref": "#/components/schemas/PreJobSiteLocationObject"}, "customer_location": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteCompositeCustomerLocationObject"}, {"type": "null"}], "description": "Customer\u2013location link for this site, if it exists"}, "contact": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteContactObject"}, {"type": "null"}], "description": "Primary contact from ProjectContact"}, "customer_contacts": {"description": "Contacts linked to the customer-location relationship", "items": {"$ref": "#/components/schemas/PreJobSiteContactObject"}, "title": "Customer Contacts", "type": "array"}, "pre_job_answers": {"items": {"$ref": "#/components/schemas/PreJobSiteAnswerObject"}, "title": "Pre Job Answers", "type": "array"}, "files": {"items": {"$ref": "#/components/schemas/PreJobSiteFileObject"}, "title": "Files", "type": "array"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "ProjectLocation.additional_information (JSON)", "title": "Additional Information"}, "om_building_address": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteOMBuildingObject"}, {"type": "null"}], "description": "O&M building for this project location when ``ProjectLocation.om_building_customer_address`` is set (same customer, type ``OM_BUILDING``). Omitted or null when no address is linked for this site."}, "required_certifications": {"description": "Per-project required certifications. Primary source is ``CustomerLocation.metadata.required_certifications``; falls back to legacy ``projects.Site.required_certifications`` (matched by site name) when the metadata entry is missing. Mirrors the list endpoint's field for uniform consumption.", "items": {"type": "string"}, "title": "Required Certifications", "type": "array"}, "other_certification_details": {"default": "", "description": "Free-text certification details. Primary source is ``CustomerLocation.metadata.other_certification_details``; falls back to legacy ``projects.Site.other_certification_details`` when the metadata entry is missing. Mirrors the list endpoint's field for uniform consumption.", "title": "Other Certification Details", "type": "string"}, "suggested_certifications": {"description": "Certificates auto-assigned to this site by the certificate mapping rules (``core.certificate_requirement_rule``), resolved from the site's region and its scope-item services. Not removable on the pre-job form.", "items": {"$ref": "#/components/schemas/PreJobSuggestedCertificationObject"}, "title": "Suggested Certifications", "type": "array"}}, "required": ["updated_at", "project_location_id", "location"], "title": "PreJobSiteCompositeResponse", "type": "object"}, "PreJobSiteCompositeContactItem": {"additionalProperties": false, "description": "One contact row in a composite PUT (upsert: set id to update, omit to create).", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing CustomerContact id; omit for a new row", "title": "Id"}, "name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Contact name", "title": "Name"}, "title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Title / role shown as `role` in pre-job read payloads", "title": "Title"}, "department": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Department", "title": "Department"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone", "title": "Phone"}, "is_primary": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Primary flag", "title": "Is Primary"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Extra notes", "title": "Additional Info"}, "is_qhse": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Mark this contact as the QHSE contact (manages a QHSE_CONTACT ProjectContact row)", "title": "Is Qhse"}}, "title": "PreJobSiteCompositeContactItem", "type": "object"}, "PreJobSiteCompositeFileLinkPatch": {"additionalProperties": false, "description": "File link upsert for pre-job instructions (FileEntityLink).", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing FileEntityLink id when updating", "title": "Id"}, "file_id": {"description": "Linked file ID", "title": "File Id", "type": "integer"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Optional JSON metadata on the link", "title": "Additional Information"}}, "required": ["file_id"], "title": "PreJobSiteCompositeFileLinkPatch", "type": "object"}, "PreJobSiteCompositeOMBuildingPatch": {"additionalProperties": false, "description": "Partial upsert for this project location's O&M ``CustomerAddress`` (``OM_BUILDING``).\n\nPersisted link is ``ProjectLocation.om_building_customer_address``; composite\nwrites do not use ``CustomerAddress.location_id`` as the join key.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing CustomerAddress id when updating", "title": "Id"}, "name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address label", "title": "Name"}, "additional_info": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional info", "title": "Additional Info"}, "address_line1": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Address line 1", "title": "Address Line1"}, "address_line2": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Address line 2", "title": "Address Line2"}, "city": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "City", "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State or region", "title": "State Region"}, "postal_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Postal code", "title": "Postal Code"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID", "title": "Timezone Id"}}, "title": "PreJobSiteCompositeOMBuildingPatch", "type": "object"}, "PreJobSiteCompositeUpdate": {"additionalProperties": false, "description": "Partial update body for PUT .../locations/{id}/pre-job (all sections optional).", "properties": {"location_custom_fields": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Patch for Location.custom_fields; keys must be a subset of the pre-job allow-list (see OpenAPI / terrain and regulations fields).", "title": "Location Custom Fields"}, "customer_location_metadata": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Patch for CustomerLocation.metadata (access, schedule, certification flags).", "title": "Customer Location Metadata"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Replace ProjectLocation.additional_information", "title": "Additional Information"}, "contacts": {"anyOf": [{"items": {"$ref": "#/components/schemas/PreJobSiteCompositeContactItem"}, "type": "array"}, {"type": "null"}], "description": "Desired CustomerContact rows for this customer_location (sync semantics in handler)", "title": "Contacts"}, "om_building": {"anyOf": [{"$ref": "#/components/schemas/PreJobSiteCompositeOMBuildingPatch"}, {"type": "null"}], "description": "Upsert O&M building for this project location, or JSON ``null`` to clear the link (``ProjectLocation.om_building_customer_address`` only; does not delete the ``CustomerAddress`` row)"}, "file_links": {"anyOf": [{"items": {"$ref": "#/components/schemas/PreJobSiteCompositeFileLinkPatch"}, "type": "array"}, {"type": "null"}], "description": "Upsert pre-job file links on the customer location", "title": "File Links"}, "remove_file_link_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "FileEntityLink ids to remove", "title": "Remove File Link Ids"}, "attach_to_project_fallback": {"default": false, "description": "If true, enable project-level file-link fallback behavior defined by the handler (including operations when CustomerLocation context is unavailable)", "title": "Attach To Project Fallback", "type": "boolean"}}, "title": "PreJobSiteCompositeUpdate", "type": "object"}, "PreJobPrefillSourceProject": {"additionalProperties": false, "description": "Another project usable as a pre-job prefill source. Paginated list row.", "properties": {"id": {"description": "Core project id", "title": "Id", "type": "integer"}, "code": {"description": "Project code", "title": "Code", "type": "string"}, "shares_target_location": {"default": false, "description": "True when this project has an active site at the same core.Location as the target pre-job site (sorted to the top as an affordance).", "title": "Shares Target Location", "type": "boolean"}, "site_services": {"description": "Services this project owes at the shared site per its latest APPROVED offer. Empty unless shares_target_location is true.", "items": {"$ref": "#/components/schemas/PreJobPrefillSourceSiteService"}, "title": "Site Services", "type": "array"}, "site_pre_job_percentage": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pre-job completion (0-100) of this project's site at the shared location \u2014 site-scoped buckets only, billing excluded. Null unless shares_target_location is true.", "title": "Site Pre Job Percentage"}}, "required": ["id", "code"], "title": "PreJobPrefillSourceProject", "type": "object"}, "PreJobPrefillSourceSiteService": {"additionalProperties": false, "description": "One service the source project has at the shared site (chip in the picker).", "properties": {"id": {"description": "Service id", "title": "Id", "type": "integer"}, "code": {"description": "Service code", "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service display name", "title": "Description"}}, "required": ["id", "code"], "title": "PreJobPrefillSourceSiteService", "type": "object"}, "PreJobPrefillSourceSite": {"additionalProperties": false, "description": "One site on a source project, surfaced to the prefill picker. Paginated list row.", "properties": {"id": {"description": "ProjectLocation id (use for pre-job composite GET)", "title": "Id", "type": "integer"}, "location_id": {"description": "Underlying core.Location id", "title": "Location Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site (location) name", "title": "Name"}}, "required": ["id", "location_id"], "title": "PreJobPrefillSourceSite", "type": "object"}, "ProjectLocationUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectLocation.", "properties": {"location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Location ID", "title": "Location Id"}, "project_contact_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project contact ID", "title": "Project Contact Id"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}}, "title": "ProjectLocationUpdate", "type": "object"}, "ReceptorListResponse": {"additionalProperties": false, "description": "GET response: ordered receptor list for one blade.", "properties": {"receptors": {"items": {"$ref": "#/components/schemas/ReceptorObject"}, "title": "Receptors", "type": "array"}}, "title": "ReceptorListResponse", "type": "object"}, "ReceptorObject": {"additionalProperties": false, "description": "Single receptor row in a GET response (includes ``updated_at``).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Receptor TurbineComponent id", "title": "Id", "type": "integer"}, "name": {"description": "Receptor label (serial_number)", "title": "Name", "type": "string"}, "radius_from_hub_m": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Distance from hub in meters", "title": "Radius From Hub M"}, "is_blade_tip": {"description": "True for the tip-of-blade receptor", "title": "Is Blade Tip", "type": "boolean"}, "component_type_id": {"description": "ComponentType id \u2014 Receptor or HV Receptor", "title": "Component Type Id", "type": "integer"}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "description": "1 or 2 for paired receptors (turbine model has double_receptors / hv_double_receptors set); NULL for non-paired. Echo back on PUT to round-trip paired rows.", "title": "Pair Index"}}, "required": ["updated_at", "id", "name", "is_blade_tip", "component_type_id"], "title": "ReceptorObject", "type": "object"}, "ReceptorItem": {"additionalProperties": false, "description": "One receptor row in a sync (PUT) body for a single blade.\n\nA receptor is a ``TurbineComponent`` with ``component_type`` Receptor or\nHV Receptor and ``parent_turbine_component`` set to the owning blade.\nThe sync endpoint operates on the receptor children of one blade at a\ntime.\n\nUpsert by ``id``: rows with ``id`` set update the matching record; rows\nwithout ``id`` create a new one. Existing rows whose ``id`` is omitted\nfrom the list are soft-deleted (full-list sync semantics).", "properties": {"id": {"anyOf": [{"exclusiveMinimum": 0, "type": "integer"}, {"type": "null"}], "description": "Existing receptor TurbineComponent id when updating; omit for create", "title": "Id"}, "name": {"description": "Receptor label (stored in TurbineComponent.serial_number)", "maxLength": 255, "minLength": 1, "title": "Name", "type": "string"}, "radius_from_hub_m": {"anyOf": [{"maximum": 200.0, "minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Distance from hub in meters (TurbineComponent.radius)", "title": "Radius From Hub M"}, "is_blade_tip": {"default": false, "description": "True for the single tip-of-blade receptor (TurbineComponent.blade_tip)", "title": "Is Blade Tip", "type": "boolean"}, "component_type_id": {"anyOf": [{"exclusiveMinimum": 0, "type": "integer"}, {"type": "null"}], "description": "Optional ComponentType id. Must point at a Receptor or HV Receptor row. Defaults to Receptor on create when omitted.", "title": "Component Type Id"}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "description": "1 or 2 for paired receptors (turbine model has double_receptors / hv_double_receptors set); NULL for non-paired. The frontend echoes back what GET returned so paired rows round-trip through a full-list PUT; on update by id the value is preserved when omitted.", "title": "Pair Index"}}, "required": ["name"], "title": "ReceptorItem", "type": "object"}, "ReceptorSyncBody": {"additionalProperties": false, "description": "PUT body for ``/blades/{id}/receptors`` \u2014 replaces the full list.", "properties": {"receptors": {"description": "Full desired receptor list for this blade. Rows missing from the list are soft-deleted; matching rows update; new rows (no id) are created with parent_turbine_component_id set to this blade.", "items": {"$ref": "#/components/schemas/ReceptorItem"}, "title": "Receptors", "type": "array"}}, "title": "ReceptorSyncBody", "type": "object"}, "BladeWithReceptorsObject": {"additionalProperties": false, "description": "One blade plus its receptor children \u2014 building block for the turbine\nconvenience GET that returns all blades + receptors in one round-trip.", "properties": {"blade": {"$ref": "#/components/schemas/_ReceptorBladeSummary"}, "receptors": {"items": {"$ref": "#/components/schemas/ReceptorObject"}, "title": "Receptors", "type": "array"}}, "required": ["blade"], "title": "BladeWithReceptorsObject", "type": "object"}, "TurbineReceptorsResponse": {"additionalProperties": false, "description": "GET ``/turbines/{id}/receptors`` \u2014 all blades + their receptors.", "properties": {"blades": {"items": {"$ref": "#/components/schemas/BladeWithReceptorsObject"}, "title": "Blades", "type": "array"}}, "title": "TurbineReceptorsResponse", "type": "object"}, "_ReceptorBladeSummary": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "serial_number": {"title": "Serial Number", "type": "string"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Position"}}, "required": ["id", "serial_number"], "title": "_ReceptorBladeSummary", "type": "object"}, "InitTurbineFromPresetResponse": {"additionalProperties": false, "description": "POST ``/turbines/{id}/receptors/init-from-preset`` \u2014 summary + the\nrefreshed per-turbine blade/receptor tree so the UI can re-render without\na follow-up GET.", "properties": {"preset_id": {"title": "Preset Id", "type": "integer"}, "preset_name": {"title": "Preset Name", "type": "string"}, "blade_count": {"description": "How many blades the turbine has (and therefore got the bulk-create applied).", "title": "Blade Count", "type": "integer"}, "receptor_template_count": {"description": "How many receptor entries the chosen preset contains. Zero means the preset is empty \u2014 no rows were created on any blade.", "title": "Receptor Template Count", "type": "integer"}, "created": {"description": "Total new TurbineComponent rows created across all blades.", "title": "Created", "type": "integer"}, "skipped_existing": {"description": "Total receptor templates skipped because a same-named receptor already existed on the blade (idempotent merge, never clobbers).", "title": "Skipped Existing", "type": "integer"}, "blades": {"items": {"$ref": "#/components/schemas/BladeWithReceptorsObject"}, "title": "Blades", "type": "array"}}, "required": ["preset_id", "preset_name", "blade_count", "receptor_template_count", "created", "skipped_existing"], "title": "InitTurbineFromPresetResponse", "type": "object"}, "InitTurbineFromPresetBody": {"additionalProperties": false, "description": "POST body for ``/turbines/{id}/receptors/init-from-preset`` \u2014 picks\nwhich named preset to seed the turbine from.", "properties": {"preset_id": {"description": "Receptor preset to copy from. Must belong to the same turbine model as the turbine being initialized.", "title": "Preset Id", "type": "integer"}}, "required": ["preset_id"], "title": "InitTurbineFromPresetBody", "type": "object"}, "ReceptorPresetListResponse": {"additionalProperties": false, "description": "GET ``/turbine-models/{id}/receptor-presets`` \u2014 all presets.", "properties": {"presets": {"items": {"$ref": "#/components/schemas/ReceptorPresetObject"}, "title": "Presets", "type": "array"}}, "title": "ReceptorPresetListResponse", "type": "object"}, "ReceptorPresetObject": {"additionalProperties": false, "description": "One named receptor preset belonging to a turbine model.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "manufacturer_turbine_model_id": {"title": "Manufacturer Turbine Model Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "receptor_count": {"default": 0, "description": "How many receptor entries this preset currently contains.", "title": "Receptor Count", "type": "integer"}}, "required": ["updated_at", "id", "manufacturer_turbine_model_id", "name"], "title": "ReceptorPresetObject", "type": "object"}, "ReceptorPresetResponse": {"additionalProperties": false, "description": "GET / POST / PATCH single-preset response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "manufacturer_turbine_model_id": {"title": "Manufacturer Turbine Model Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "receptor_count": {"default": 0, "description": "How many receptor entries this preset currently contains.", "title": "Receptor Count", "type": "integer"}}, "required": ["updated_at", "id", "manufacturer_turbine_model_id", "name"], "title": "ReceptorPresetResponse", "type": "object"}, "ReceptorPresetCreate": {"additionalProperties": false, "description": "POST body for creating a preset under a turbine model.", "properties": {"name": {"description": "Preset name (e.g. 'Standard'). Cannot be blank.", "maxLength": 255, "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"maxLength": 2000, "type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["name"], "title": "ReceptorPresetCreate", "type": "object"}, "ReceptorPresetUpdate": {"additionalProperties": false, "description": "PATCH body for renaming / re-describing a preset.", "properties": {"name": {"anyOf": [{"maxLength": 255, "minLength": 1, "type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"maxLength": 2000, "type": "string"}, {"type": "null"}], "title": "Description"}}, "title": "ReceptorPresetUpdate", "type": "object"}, "LpsResultBlade": {"additionalProperties": false, "properties": {"blade": {"additionalProperties": {"anyOf": [{}, {"type": "null"}]}, "description": "Blade summary: {id, serial_number, position}.", "title": "Blade", "type": "object"}, "receptors": {"items": {"$ref": "#/components/schemas/LpsResultReceptor"}, "title": "Receptors", "type": "array"}, "dataplate_image": {"anyOf": [{"$ref": "#/components/schemas/LpsResultBladeDataplate"}, {"type": "null"}], "description": "Most-recent BLADE_DATAPLATE FileEntityLink for this blade, when one exists. The FE composes a download URL via the standard core file helpers."}}, "required": ["blade"], "title": "LpsResultBlade", "type": "object"}, "LpsResultBladeDataplate": {"additionalProperties": false, "description": "Latest BLADE_DATAPLATE image attached to a blade TurbineComponent.", "properties": {"file_id": {"title": "File Id", "type": "integer"}, "file_name": {"title": "File Name", "type": "string"}}, "required": ["file_id", "file_name"], "title": "LpsResultBladeDataplate", "type": "object"}, "LpsResultCell": {"additionalProperties": false, "description": "One side (SS or PS) of one receptor's measurement.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing WorkorderResult.id; null when no row exists yet.", "title": "Id"}, "reading": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Numeric reading. Null when no_reading=True (open-circuit / no measurement).", "title": "Reading"}, "unit": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Result unit \u2014 one of mOhm, Ohm, MOhm.", "title": "Unit"}, "no_reading": {"default": false, "description": "True when the receptor was open-circuit / no reading was taken.", "title": "No Reading", "type": "boolean"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}}, "title": "LpsResultCell", "type": "object"}, "LpsResultReceptor": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "radius_from_hub_m": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Radius From Hub M"}, "is_blade_tip": {"default": false, "title": "Is Blade Tip", "type": "boolean"}, "component_type_id": {"title": "Component Type Id", "type": "integer"}, "pair_index": {"anyOf": [{"enum": [1, 2], "type": "integer"}, {"type": "null"}], "title": "Pair Index"}, "cells": {"additionalProperties": {"anyOf": [{"$ref": "#/components/schemas/LpsResultCell"}, {"type": "null"}]}, "description": "Keyed by 'ss' / 'ps'. A null value means no measurement yet for that side.", "title": "Cells", "type": "object"}}, "required": ["id", "name", "component_type_id"], "title": "LpsResultReceptor", "type": "object"}, "LpsResultsContextResponse": {"additionalProperties": false, "description": "GET ``/service-order-lines/{sol_id}/lps-results`` \u2014 per-blade matrix.", "properties": {"service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}, "turbine": {"$ref": "#/components/schemas/LpsResultsTurbineObject"}, "blades": {"items": {"$ref": "#/components/schemas/LpsResultBlade"}, "title": "Blades", "type": "array"}}, "required": ["service_order_line_id", "turbine"], "title": "LpsResultsContextResponse", "type": "object"}, "LpsResultsTurbineObject": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "manufacturer_turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Manufacturer Turbine Model Id"}}, "required": ["id"], "title": "LpsResultsTurbineObject", "type": "object"}, "LpsResultsUpsertResponse": {"additionalProperties": false, "description": "PUT response = the upsert count + the refreshed capture context.", "properties": {"service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}, "turbine": {"$ref": "#/components/schemas/LpsResultsTurbineObject"}, "blades": {"items": {"$ref": "#/components/schemas/LpsResultBlade"}, "title": "Blades", "type": "array"}, "upserted": {"description": "How many cells were written (created or updated).", "title": "Upserted", "type": "integer"}}, "required": ["service_order_line_id", "turbine", "upserted"], "title": "LpsResultsUpsertResponse", "type": "object"}, "LpsResultsUpsertBody": {"additionalProperties": false, "properties": {"cells": {"description": "Flat list of cell updates.", "items": {"$ref": "#/components/schemas/LpsResultsUpsertCell"}, "title": "Cells", "type": "array"}}, "required": ["cells"], "title": "LpsResultsUpsertBody", "type": "object"}, "LpsResultsUpsertCell": {"additionalProperties": false, "description": "One row of the upsert payload.", "properties": {"receptor_id": {"description": "TurbineComponent.id of the receptor (NOT the blade).", "title": "Receptor Id", "type": "integer"}, "side": {"description": "SUCTION_SIDE or PRESSURE_SIDE.", "title": "Side", "type": "string"}, "reading": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Reading"}, "unit": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Unit"}, "no_reading": {"default": false, "title": "No Reading", "type": "boolean"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional operator comment. When the key is omitted entirely, any stored comment is preserved (the OpsHub UI no longer sends it).", "title": "Comment"}}, "required": ["receptor_id", "side"], "title": "LpsResultsUpsertCell", "type": "object"}, "ProjectOfferResponse": {"additionalProperties": false, "description": "Schema for ProjectOffer response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project offer ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "currency": {"$ref": "#/components/schemas/CurrencyObject", "description": "Currency information"}, "discount": {"description": "Discount amount", "title": "Discount", "type": "number"}, "total_amount": {"description": "Total amount (calculated from offer items)", "title": "Total Amount", "type": "number"}, "status": {"description": "Offer status", "title": "Status", "type": "string"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version number", "title": "Version"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Offer type (main, amendment)", "title": "Type"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Reason for change", "title": "Change Reason"}, "reviewer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Reviewer user ID", "title": "Reviewer Id"}, "gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Gross margin percentage", "title": "Gross Margin"}, "adjusted_gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjusted gross margin percentage", "title": "Adjusted Gross Margin"}, "crew_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Technicians in one crew", "examples": [3], "title": "Crew Size"}, "crew_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Number of crews working the deal", "examples": [1], "title": "Crew Count"}, "working_days": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Working days on site, taken from the longest-running crew", "examples": [15.0], "title": "Working Days"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comment"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Required approver role", "title": "Required Approver Role"}}, "required": ["updated_at", "id", "project_id", "currency", "discount", "total_amount", "status"], "title": "ProjectOfferResponse", "type": "object"}, "ProjectOfferSendForApprovalRequest": {"additionalProperties": false, "description": "Body for sending a draft offer for approval.", "properties": {"sales_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales comment/context shown to the approver", "title": "Sales Comment"}}, "title": "ProjectOfferSendForApprovalRequest", "type": "object"}, "ProjectOfferRejectRequest": {"additionalProperties": false, "description": "Body for rejecting a pending offer.", "properties": {"message": {"description": "Rejection reason (stored in change_reason)", "title": "Message", "type": "string"}}, "required": ["message"], "title": "ProjectOfferRejectRequest", "type": "object"}, "ProjectOfferHistoryResponse": {"additionalProperties": false, "description": "Schema for an offer history row (a non-draft offer version).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project offer ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "currency": {"$ref": "#/components/schemas/CurrencyObject", "description": "Currency information"}, "discount": {"deprecated": true, "description": "Deprecated \u2014 stored offer-level value with undefined business meaning; never applied to totals", "title": "Discount", "type": "number"}, "total_amount": {"description": "Total amount (calculated from offer items)", "title": "Total Amount", "type": "number"}, "status": {"description": "Offer status", "title": "Status", "type": "string"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version number", "title": "Version"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Offer type (main, amendment)", "title": "Type"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Reason for change", "title": "Change Reason"}, "reviewer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Reviewer user ID", "title": "Reviewer Id"}, "gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Gross margin percentage", "title": "Gross Margin"}, "adjusted_gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjusted gross margin percentage", "title": "Adjusted Gross Margin"}, "crew_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Technicians in one crew", "examples": [3], "title": "Crew Size"}, "crew_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Number of crews working the deal", "examples": [1], "title": "Crew Count"}, "working_days": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Working days on site, taken from the longest-running crew", "examples": [15.0], "title": "Working Days"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comment"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Required approver role", "title": "Required Approver Role"}, "date": {"description": "When this offer version was created", "format": "date-time", "title": "Date", "type": "string"}, "requestor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Requestor user ID", "title": "Requestor Id"}, "requestor_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email of the user who sent this version for approval", "title": "Requestor Email"}, "reviewer_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email of the user who reviewed (approved/rejected) this version", "title": "Reviewer Email"}}, "required": ["updated_at", "id", "project_id", "currency", "discount", "total_amount", "status", "date"], "title": "ProjectOfferHistoryResponse", "type": "object"}, "ProjectOfferQueryParams": {"additionalProperties": false, "description": "Query parameters for the project offers list endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by status", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by offer status", "title": "Status"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by version number", "title": "Version"}}, "title": "ProjectOfferQueryParams", "type": "object"}, "ProjectOfferCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectOffer.", "properties": {"currency_id": {"description": "Currency ID", "title": "Currency Id", "type": "integer"}, "discount": {"default": 0, "description": "Discount amount", "title": "Discount", "type": "number"}, "status": {"default": "Draft", "description": "Offer status", "title": "Status", "type": "string"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version number", "title": "Version"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Offer type (main, amendment)", "title": "Type"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Reason for change", "title": "Change Reason"}, "reviewer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Reviewer user ID", "title": "Reviewer Id"}, "gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Gross margin percentage", "title": "Gross Margin"}, "adjusted_gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjusted gross margin percentage", "title": "Adjusted Gross Margin"}, "crew_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Technicians in one crew", "examples": [3], "title": "Crew Size"}, "crew_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Number of crews working the deal", "examples": [1], "title": "Crew Count"}, "working_days": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Working days on site, taken from the longest-running crew", "examples": [15.0], "title": "Working Days"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comment"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Required approver role", "title": "Required Approver Role"}}, "required": ["currency_id"], "title": "ProjectOfferCreate", "type": "object"}, "ProjectOfferUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectOffer.", "properties": {"currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Currency ID", "title": "Currency Id"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount amount", "title": "Discount"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Offer status", "title": "Status"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version number", "title": "Version"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Offer type (main, amendment)", "title": "Type"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Reason for change", "title": "Change Reason"}, "reviewer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Reviewer user ID", "title": "Reviewer Id"}, "gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Gross margin percentage", "title": "Gross Margin"}, "adjusted_gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjusted gross margin percentage", "title": "Adjusted Gross Margin"}, "crew_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Technicians in one crew", "examples": [3], "title": "Crew Size"}, "crew_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Number of crews working the deal", "examples": [1], "title": "Crew Count"}, "working_days": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Working days on site, taken from the longest-running crew", "examples": [15.0], "title": "Working Days"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comments", "title": "Comment"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Required approver role", "title": "Required Approver Role"}}, "title": "ProjectOfferUpdate", "type": "object"}, "ProjectBillingCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectBilling.", "properties": {"billing_lead_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project contact acting as billing lead", "title": "Billing Lead Id"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing address", "title": "Address"}, "address_state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing address state", "title": "Address State"}, "invoice_recipient_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer receiving the invoice", "title": "Invoice Recipient Id"}, "payment_terms_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text comment for payment terms", "title": "Payment Terms Comment"}, "payment_terms": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Payment terms code", "title": "Payment Terms"}, "purchase_order_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether a purchase order is required", "title": "Purchase Order Required"}, "purchase_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Purchase order number", "title": "Purchase Order Number"}, "purchase_order_value": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Purchase order value", "title": "Purchase Order Value"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency"}, "invoicing_method": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing method", "title": "Invoicing Method"}, "invoicing_instructions": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing instructions", "title": "Invoicing Instructions"}, "invoicing_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoicing email(s)", "title": "Invoicing Email"}, "additional_invoice_approval_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether an additional invoice approval is required", "title": "Additional Invoice Approval Required"}, "invoice_approver_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice approver full name", "title": "Invoice Approver Full Name"}, "invoice_approver_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice approver email", "title": "Invoice Approver Email"}, "invoice_frequency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice frequency", "title": "Invoice Frequency"}, "sales_tax_exemption_certificate": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether a sales tax exemption certificate applies", "title": "Sales Tax Exemption Certificate"}, "sales_tax_exemption_certificate_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales tax exemption certificate number", "title": "Sales Tax Exemption Certificate Number"}, "receive_daily_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Would you like to receive daily reports?'", "title": "Receive Daily Reports"}, "specific_report_requirements": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Specific report requirements?'", "title": "Specific Report Requirements"}, "receive_draft_charge_statements": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Answer to 'Do you want to receive draft charge statements?'", "title": "Receive Draft Charge Statements"}, "draft_charge_statement_frequency": {"anyOf": [{"enum": ["WEEKLY", "MONTHLY"], "type": "string"}, {"type": "null"}], "description": "Draft charge statement delivery frequency", "title": "Draft Charge Statement Frequency"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Vendor ID", "title": "Vendor Id"}}, "title": "ProjectBillingCreate", "type": "object"}, "ProjectReportRecipientObject": {"additionalProperties": false, "description": "Nested report recipient object (a linked project contact).", "properties": {"id": {"description": "ProjectReportRecipient link ID", "title": "Id", "type": "integer"}, "project_contact_id": {"description": "Linked project contact ID", "title": "Project Contact Id", "type": "integer"}, "project_contact_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Linked contact's name", "title": "Project Contact Name"}, "project_contact_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Linked contact's email", "title": "Project Contact Email"}}, "required": ["id", "project_contact_id"], "title": "ProjectReportRecipientObject", "type": "object"}, "ProjectReportTypeResponse": {"additionalProperties": false, "description": "Schema for ProjectReportType response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project report type ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "report_type": {"$ref": "#/components/schemas/ReportTypeObject", "description": "Report type"}, "requirement_file_ids": {"description": "Specific report requirement attachment file IDs", "items": {"type": "string"}, "title": "Requirement File Ids", "type": "array"}, "requirement_notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional free-text specific report requirements", "title": "Requirement Notes"}, "recipients": {"description": "Linked report recipients", "items": {"$ref": "#/components/schemas/ProjectReportRecipientObject"}, "title": "Recipients", "type": "array"}, "recipient_emails": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Selected recipient emails for this report type. None = no email-based selection saved (legacy row), [] = the user explicitly removed every recipient", "title": "Recipient Emails"}}, "required": ["updated_at", "id", "project_id", "report_type"], "title": "ProjectReportTypeResponse", "type": "object"}, "ReportTypeObject": {"additionalProperties": false, "description": "Nested report type object (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "code", "name"], "title": "ReportTypeObject", "type": "object"}, "ProjectReportTypeCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectReportType.", "properties": {"report_type_id": {"description": "Report type to subscribe to", "title": "Report Type Id", "type": "integer"}, "requirement_file_ids": {"description": "Specific report requirement attachment file IDs", "items": {"type": "string"}, "title": "Requirement File Ids", "type": "array"}, "requirement_notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional free-text specific report requirements", "title": "Requirement Notes"}, "recipient_project_contact_ids": {"description": "Project contact IDs that receive this report", "items": {"type": "integer"}, "title": "Recipient Project Contact Ids", "type": "array"}, "recipient_emails": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Selected recipient emails for this report type (the form pre-selects the RFI report-recipient contacts; free-text addresses are allowed). None = no email-based selection, [] = explicitly no recipients", "title": "Recipient Emails"}}, "required": ["report_type_id"], "title": "ProjectReportTypeCreate", "type": "object"}, "ProjectReportTypeUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectReportType (partial).", "properties": {"requirement_file_ids": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Specific report requirement attachment file IDs", "title": "Requirement File Ids"}, "requirement_notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional free-text specific report requirements", "title": "Requirement Notes"}, "recipient_project_contact_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Project contact IDs that receive this report (None leaves recipients unchanged, [] clears them)", "title": "Recipient Project Contact Ids"}, "recipient_emails": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Selected recipient emails (None leaves them unchanged, [] clears them)", "title": "Recipient Emails"}}, "title": "ProjectReportTypeUpdate", "type": "object"}, "ProjectOfferItemQueryParams": {"additionalProperties": false, "description": "Query parameters for project offer items endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by description", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}, "is_service": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item's service is a service (vs addon/material)", "title": "Is Service"}}, "title": "ProjectOfferItemQueryParams", "type": "object"}, "ProjectOfferItemResponse": {"additionalProperties": false, "description": "Schema for ProjectOfferItem response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project offer item ID", "title": "Id", "type": "integer"}, "offer_id": {"description": "Offer ID", "title": "Offer Id", "type": "integer"}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationObject"}, {"type": "null"}], "description": "Location information (from project_location.location)"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceObject"}, {"type": "null"}], "description": "Service information"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price", "title": "Price"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount", "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjustment", "title": "Adjustment"}, "unit_price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Calculated unit price", "title": "Unit Price"}, "amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Amount", "title": "Amount"}, "turbine_manufacturer": {"anyOf": [{"$ref": "#/components/schemas/ManufacturerObject"}, {"type": "null"}], "description": "Turbine manufacturer information"}, "turbine_model": {"anyOf": [{"$ref": "#/components/schemas/TurbineModelObject"}, {"type": "null"}], "description": "Turbine model information"}, "component_manufacturer": {"anyOf": [{"$ref": "#/components/schemas/ManufacturerObject"}, {"type": "null"}], "description": "Component manufacturer information"}, "component_model": {"anyOf": [{"$ref": "#/components/schemas/ManufacturerComponentModelObject"}, {"type": "null"}], "description": "Component model information"}, "coefficients": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Coefficients as JSON (object or array)", "title": "Coefficients"}, "group_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Group ID", "title": "Group Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Item description", "title": "Description"}, "pricing_unit": {"anyOf": [{"$ref": "#/components/schemas/PricingUnitNestedResponse"}, {"type": "null"}], "description": "Pricing unit information"}, "initial_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Initial offer item ID (self-reference)", "title": "Initial Offer Item Id"}}, "required": ["updated_at", "id", "offer_id"], "title": "ProjectOfferItemResponse", "type": "object"}, "ProjectOfferItemCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectOfferItem.", "properties": {"location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price", "title": "Price"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount", "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjustment", "title": "Adjustment"}, "amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Amount", "title": "Amount"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer ID", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Turbine Model Id"}, "component_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component manufacturer ID", "title": "Component Manufacturer Id"}, "manufacturer_component_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer component model ID", "title": "Manufacturer Component Model Id"}, "coefficients": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Coefficients as JSON (object or array)", "title": "Coefficients"}, "group_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Group ID", "title": "Group Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Item description", "title": "Description"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pricing unit ID", "title": "Pricing Unit Id"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated legacy field. Ignored if provided.", "title": "Type"}, "unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated legacy field. Use pricing_unit_id.", "title": "Unit Type"}, "initial_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Initial offer item ID (self-reference)", "title": "Initial Offer Item Id"}}, "title": "ProjectOfferItemCreate", "type": "object"}, "ProjectOfferItemUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectOfferItem.", "properties": {"location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price", "title": "Price"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount", "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjustment", "title": "Adjustment"}, "amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Amount", "title": "Amount"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer ID", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Turbine Model Id"}, "component_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component manufacturer ID", "title": "Component Manufacturer Id"}, "manufacturer_component_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Manufacturer component model ID", "title": "Manufacturer Component Model Id"}, "coefficients": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Coefficients as JSON (object or array)", "title": "Coefficients"}, "group_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Group ID", "title": "Group Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Item description", "title": "Description"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pricing unit ID", "title": "Pricing Unit Id"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated legacy field. Ignored if provided.", "title": "Type"}, "unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated legacy field. Use pricing_unit_id.", "title": "Unit Type"}, "initial_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Initial offer item ID (self-reference)", "title": "Initial Offer Item Id"}}, "title": "ProjectOfferItemUpdate", "type": "object"}, "CommercialOfferInboxQueryParams": {"additionalProperties": false, "description": "Query parameters for the commercial-offer approvals inbox.", "properties": {"page": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "page_size": {"default": 50, "maximum": 200, "minimum": 1, "title": "Page Size", "type": "integer"}, "include_approved": {"default": false, "title": "Include Approved", "type": "boolean"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Required Approver Role"}, "ordering": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "-offer_id", "title": "Ordering"}}, "title": "CommercialOfferInboxQueryParams", "type": "object"}, "CommercialOfferInboxRow": {"additionalProperties": false, "description": "Cross-project approvals-inbox row: the latest non-draft offer per project.", "properties": {"offer_id": {"description": "Project offer ID (bulk-approve payload)", "title": "Offer Id", "type": "integer"}, "core_project_id": {"description": "Core project ID", "title": "Core Project Id", "type": "integer"}, "project_builder_id": {"description": "Legacy project UUID (row links)", "format": "uuid", "title": "Project Builder Id", "type": "string"}, "updated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Last update timestamp", "title": "Updated At"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Offer version number", "title": "Version"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency code", "title": "Currency"}, "total_amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount (sum of item amounts)", "title": "Total Amount"}, "discount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "deprecated": true, "description": "Deprecated \u2014 stored offer-level value with undefined business meaning; never applied to totals", "title": "Discount"}, "status": {"description": "Offer status", "title": "Status", "type": "string"}, "requestor_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email of the user who sent this version for approval", "title": "Requestor Email"}, "reviewer_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email of the user who reviewed this version", "title": "Reviewer Email"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales comment", "title": "Comment"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Required approver role", "title": "Required Approver Role"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project code", "title": "Project Code"}, "company_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Customer/company name", "title": "Company Name"}}, "required": ["offer_id", "core_project_id", "project_builder_id", "status"], "title": "CommercialOfferInboxRow", "type": "object"}, "CommercialOfferInboxBulkApproveResponse": {"additionalProperties": false, "description": "Response describing which offers were approved or skipped.", "properties": {"approved": {"items": {"type": "integer"}, "title": "Approved", "type": "array"}, "skipped": {"items": {"type": "integer"}, "title": "Skipped", "type": "array"}}, "required": ["approved", "skipped"], "title": "CommercialOfferInboxBulkApproveResponse", "type": "object"}, "CommercialOfferInboxBulkApproveRequest": {"additionalProperties": false, "description": "Request payload for bulk commercial offer approval.", "properties": {"ids": {"description": "Project offer IDs to approve", "items": {"type": "integer"}, "title": "Ids", "type": "array"}}, "required": ["ids"], "title": "CommercialOfferInboxBulkApproveRequest", "type": "object"}, "ProjectScopeItemQueryParams": {"additionalProperties": false, "description": "Query parameters for project scope items endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by location, turbine, service code/description, component type, or turbine component identifiers", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service ID", "title": "Service Id"}}, "title": "ProjectScopeItemQueryParams", "type": "object"}, "ProjectScopeItemResponse": {"additionalProperties": false, "description": "Schema for ProjectScopeItem response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project scope item ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "service_order_line_refs": {"description": "Live (non-cancelled) SOLs generated from this scope item", "items": {"$ref": "#/components/schemas/ScopeItemServiceOrderLineRef"}, "title": "Service Order Line Refs", "type": "array"}, "location": {"$ref": "#/components/schemas/ProjectScopeLocationObject", "description": "Location information (with GPS coordinates for the map)"}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeTurbineObject"}, {"type": "null"}], "description": "Turbine information (with GPS coordinates for the map)"}, "component_type": {"anyOf": [{"$ref": "#/components/schemas/ComponentTypeObject"}, {"type": "null"}], "description": "Component type information"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeTurbineComponentObject"}, {"type": "null"}], "description": "Turbine component information"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "turbine_component_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component serial number", "title": "Turbine Component Serial Number"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceObject"}, {"type": "null"}], "description": "Service information"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Amount", "title": "Amount"}}, "required": ["updated_at", "id", "project_id", "location"], "title": "ProjectScopeItemResponse", "type": "object"}, "ProjectScopeLocationObject": {"additionalProperties": false, "description": "Nested location object for scope rows, carrying geo-coordinates.\n\nUsed as the map fallback when a turbine has no coordinates of its own\n(``core.Location.latitude``/``longitude``).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"anyOf": [{"$ref": "#/components/schemas/LocationType"}, {"type": "null"}]}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Location GPS latitude", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Location GPS longitude", "title": "Longitude"}}, "required": ["id", "name"], "title": "ProjectScopeLocationObject", "type": "object"}, "ProjectScopeTurbineComponentObject": {"additionalProperties": false, "description": "Nested turbine component descriptor for project scope rows.", "properties": {"id": {"title": "Id", "type": "integer"}, "serial_number": {"title": "Serial Number", "type": "string"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Position"}}, "required": ["id", "serial_number"], "title": "ProjectScopeTurbineComponentObject", "type": "object"}, "ProjectScopeTurbineObject": {"additionalProperties": false, "description": "Nested turbine object for scope rows, carrying geo-coordinates.\n\nCoordinates power the Project scope map view. They come straight off\n``core.Turbine`` (``latitude``/``longitude`` DecimalFields, backfilled from\nthe free-text ``coordinates`` string by migration\n``0058_populate_lat_lng_from_coordinates``). Pydantic ``from_attributes``\nreads them off the already ``select_related``-loaded turbine, so exposing\nthem adds no query.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Turbine GPS latitude", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Turbine GPS longitude", "title": "Longitude"}}, "required": ["id", "name"], "title": "ProjectScopeTurbineObject", "type": "object"}, "ScopeItemServiceOrderLineRef": {"additionalProperties": false, "description": "A live SOL generated from a scope item (for linking from scope UIs).", "properties": {"id": {"description": "ServiceOrderLine ID", "title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SOL number", "title": "Number"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SOL status", "title": "Status"}}, "required": ["id"], "title": "ScopeItemServiceOrderLineRef", "type": "object"}, "ProjectScopeItemCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectScopeItem.", "properties": {"location_id": {"description": "Location ID", "title": "Location Id", "type": "integer"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID", "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Amount", "title": "Amount"}, "commercial_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Commercial offer item ID from latest approved version", "title": "Commercial Offer Item Id"}}, "required": ["location_id"], "title": "ProjectScopeItemCreate", "type": "object"}, "ProjectScopeItemUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectScopeItem.", "properties": {"location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Location ID", "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID", "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "additional_information": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Additional information as JSON", "title": "Additional Information"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Amount", "title": "Amount"}, "commercial_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Commercial offer item ID from latest approved version", "title": "Commercial Offer Item Id"}}, "title": "ProjectScopeItemUpdate", "type": "object"}, "ProjectScopeItemBulkCreate": {"additionalProperties": false, "description": "Schema for bulk creating ProjectScopeItems for multiple turbines.", "properties": {"location_id": {"description": "Location ID", "title": "Location Id", "type": "integer"}, "turbine_ids": {"description": "List of turbine IDs", "items": {"type": "integer"}, "minItems": 1, "title": "Turbine Ids", "type": "array"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID", "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "commercial_offer_item_id": {"description": "Commercial offer item ID from latest approved version", "title": "Commercial Offer Item Id", "type": "integer"}}, "required": ["location_id", "turbine_ids", "commercial_offer_item_id"], "title": "ProjectScopeItemBulkCreate", "type": "object"}, "ProjectResourceSetQueryParams": {"additionalProperties": false, "description": "Query parameters for project resource sets endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project location ID", "title": "Project Location Id"}, "active_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start of the activity window (inclusive). Together with active_to, returns only sets that performed at least one workorder activity whose SOL-local day falls inside [active_from, active_to]. Attribution goes through dispatch.workorder_resource_set links including soft-deleted ones, so reassigned workorders still credit the team that worked them.", "title": "Active From"}, "active_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End of the activity window (inclusive). Paired with active_from.", "title": "Active To"}}, "title": "ProjectResourceSetQueryParams", "type": "object"}, "NestedIdOnly": {"additionalProperties": false, "description": "Generic nested object with just id (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "NestedIdOnly", "type": "object"}, "ProjectObject": {"additionalProperties": false, "description": "Nested project object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "ProjectObject", "type": "object"}, "ProjectResourceSetItemOutput": {"additionalProperties": false, "description": "Output schema for project resource set item in responses.", "properties": {"id": {"description": "ProjectResourceSetItem ID", "title": "Id", "type": "integer"}, "resource_id": {"description": "Resource ID", "title": "Resource Id", "type": "integer"}, "resource_type": {"description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}, "resource_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Resource Full Name"}, "resource_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource email", "title": "Resource Email"}}, "required": ["id", "resource_id", "resource_type"], "title": "ProjectResourceSetItemOutput", "type": "object"}, "ProjectResourceSetResponse": {"additionalProperties": false, "description": "Schema for ProjectResourceSet response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project resource set ID", "title": "Id", "type": "integer"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectObject"}, {"type": "null"}], "description": "Project information"}, "project_location": {"anyOf": [{"$ref": "#/components/schemas/NestedIdOnly"}, {"type": "null"}], "description": "Project location information"}, "name": {"description": "Set name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set description", "title": "Description"}, "project_planned_resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Planned resource set this roster set was promoted from. Null only for sets predating the promote flow and for the dispatching board's robot-set sync.", "title": "Project Planned Resource Set Id"}, "project_planned_resource_set_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status of that planned set. Drives the delete guard: a roster set can only be deleted while its planned set is SUGGESTED or APPROVED. Null when there is no planned set to check.", "title": "Project Planned Resource Set Status"}, "project_planned_resource_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of that planned set, so the UI can say WHICH one this roster came from. One planned set can back several roster sets, and a roster can be renamed away from the name it was promoted with.", "title": "Project Planned Resource Set Name"}, "set_items": {"description": "Resource set items", "items": {"$ref": "#/components/schemas/ProjectResourceSetItemOutput"}, "title": "Set Items", "type": "array"}}, "required": ["updated_at", "id", "name"], "title": "ProjectResourceSetResponse", "type": "object"}, "ProjectResourceSetCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectResourceSet.", "properties": {"name": {"description": "Set name", "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set description", "title": "Description"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "set_items": {"anyOf": [{"items": {"$ref": "#/components/schemas/ProjectResourceSetItemInput"}, "type": "array"}, {"type": "null"}], "description": "Resource set items to create with the set", "title": "Set Items"}}, "required": ["name"], "title": "ProjectResourceSetCreate", "type": "object"}, "ProjectResourceSetItemInput": {"additionalProperties": false, "description": "Input schema for project resource set item in create/update requests.", "properties": {"resource_id": {"description": "Resource ID", "title": "Resource Id", "type": "integer"}, "resource_type": {"description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}}, "required": ["resource_id", "resource_type"], "title": "ProjectResourceSetItemInput", "type": "object"}, "ProjectResourceSetUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectResourceSet.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Set name", "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set description", "title": "Description"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "set_items": {"anyOf": [{"items": {"$ref": "#/components/schemas/ProjectResourceSetItemInput"}, "type": "array"}, {"type": "null"}], "description": "Resource set items (None=unchanged, []=clear all, [...]= replace)", "title": "Set Items"}}, "title": "ProjectResourceSetUpdate", "type": "object"}, "MaterializePlannedInput": {"additionalProperties": false, "description": "Body for promoting a planned resource set into a roster set.", "properties": {"planned_resource_set_id": {"title": "Planned Resource Set Id", "type": "integer"}, "resource_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Resource Ids"}}, "required": ["planned_resource_set_id"], "title": "MaterializePlannedInput", "type": "object"}, "ProjectResourceSetActivityDay": {"additionalProperties": false, "description": "One worked day of a project resource set within the queried window.", "properties": {"day": {"description": "SOL-local calendar day", "format": "date", "title": "Day", "type": "string"}, "service_order_line_ids": {"description": "SOLs the set ran activities on during this day", "items": {"type": "integer"}, "title": "Service Order Line Ids", "type": "array"}, "has_activity": {"default": false, "description": "The set ran at least one workorder activity this day", "title": "Has Activity", "type": "boolean"}, "has_delay": {"default": false, "description": "The set logged at least one delay/idle this day", "title": "Has Delay", "type": "boolean"}}, "required": ["day"], "title": "ProjectResourceSetActivityDay", "type": "object"}, "ProjectResourceSetActivityDaysResponse": {"additionalProperties": false, "description": "Per-set workorder-activity days for the execution overview team grid.", "properties": {"project_resource_set_id": {"description": "Project resource set ID", "title": "Project Resource Set Id", "type": "integer"}, "days": {"description": "Activity days inside [active_from, active_to], ascending", "items": {"$ref": "#/components/schemas/ProjectResourceSetActivityDay"}, "title": "Days", "type": "array"}}, "required": ["project_resource_set_id"], "title": "ProjectResourceSetActivityDaysResponse", "type": "object"}, "ProjectPlannedResourceSetQueryParams": {"additionalProperties": false, "description": "Query parameters for planned resource sets endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project location ID", "title": "Project Location Id"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}, {"type": "null"}], "description": "Filter by status"}}, "title": "ProjectPlannedResourceSetQueryParams", "type": "object"}, "ProjectPlannedResourceSetStatus": {"description": "All planned-resource-set statuses (approval pipeline + deployment lifecycle).\n\nMirrors ``core.models.projects.ProjectPlannedResourceSetStatus`` \u2014 keep both\nin sync.", "enum": ["PLANNED", "SUGGESTED", "APPROVED", "PLANNING", "EXECUTION", "FIELD_COMPLETED", "REJECTED"], "title": "ProjectPlannedResourceSetStatus", "type": "string"}, "ProjectPlannedResourceSetItemEmbeddedOutput": {"additionalProperties": false, "description": "Embedded planned item: same shape as a PRS item plus approval status.\n\n``resource_id`` widens to optional here and stays required on the roster base\nit inherits from: a *planned* leg can be an unassigned booking (the robot set\nis named later), while a materialized roster member always has its resource.", "properties": {"id": {"description": "ProjectResourceSetItem ID", "title": "Id", "type": "integer"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource ID; null on an unassigned leg", "title": "Resource Id"}, "resource_type": {"description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}, "resource_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Resource Full Name"}, "resource_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource email", "title": "Resource Email"}, "status": {"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus", "description": "Approval lifecycle status"}}, "required": ["id", "resource_type", "status"], "title": "ProjectPlannedResourceSetItemEmbeddedOutput", "type": "object"}, "ProjectPlannedResourceSetResponse": {"additionalProperties": false, "description": "Schema for ProjectPlannedResourceSet response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Planned resource set ID", "title": "Id", "type": "integer"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectObject"}, {"type": "null"}], "description": "Project information"}, "project_location": {"anyOf": [{"$ref": "#/components/schemas/NestedIdOnly"}, {"type": "null"}], "description": "Project location information"}, "name": {"description": "Set name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set description", "title": "Description"}, "status": {"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus", "description": "Approval lifecycle status"}, "set_items": {"description": "Planned resource set items", "items": {"$ref": "#/components/schemas/ProjectPlannedResourceSetItemEmbeddedOutput"}, "title": "Set Items", "type": "array"}, "planned_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Earliest planned start across set items (min, NULL if none)", "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Latest planned end across set items (max, NULL if none)", "title": "Planned End Date"}}, "required": ["updated_at", "id", "name", "status"], "title": "ProjectPlannedResourceSetResponse", "type": "object"}, "ProjectPlannedResourceSetCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectPlannedResourceSet.", "properties": {"name": {"description": "Set name", "minLength": 1, "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set description", "title": "Description"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "status": {"allOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}], "default": "APPROVED", "description": "Set-deployment status (defaults to APPROVED on create)"}}, "required": ["name"], "title": "ProjectPlannedResourceSetCreate", "type": "object"}, "ProjectPlannedResourceSetUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectPlannedResourceSet.", "properties": {"name": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Set name", "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set description", "title": "Description"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}, {"type": "null"}], "description": "Approval lifecycle status"}}, "title": "ProjectPlannedResourceSetUpdate", "type": "object"}, "ProjectPlannedResourceSetItemQueryParams": {"additionalProperties": false, "description": "Query parameters for planned resource set items endpoint.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by resource type (ROBOT or TECHNICIAN)", "title": "Resource Type"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}, {"type": "null"}], "description": "Filter by status"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by is_lead flag", "title": "Is Lead"}}, "title": "ProjectPlannedResourceSetItemQueryParams", "type": "object"}, "ProjectPlannedResourceSetItemResponse": {"additionalProperties": false, "description": "Schema for ProjectPlannedResourceSetItem response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Planned resource set item ID", "title": "Id", "type": "integer"}, "project_planned_resource_set_id": {"description": "Planned resource set ID", "title": "Project Planned Resource Set Id", "type": "integer"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource ID; null on an unassigned leg", "title": "Resource Id"}, "resource_type": {"description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}, "status": {"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus", "description": "Approval lifecycle status"}, "resource_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Resource Full Name"}, "resource_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource email", "title": "Resource Email"}}, "required": ["updated_at", "id", "project_planned_resource_set_id", "resource_type", "status"], "title": "ProjectPlannedResourceSetItemResponse", "type": "object"}, "ProjectPlannedResourceSetItemCreate": {"additionalProperties": false, "description": "Schema for creating a ProjectPlannedResourceSetItem.", "properties": {"resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource ID. Omit or send null to book an unassigned ROBOT leg (dates now, set chosen later); allowed only while the leg is PLANNED.", "title": "Resource Id"}, "resource_type": {"description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}, "status": {"allOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}], "default": "PLANNED", "description": "Approval lifecycle status"}}, "required": ["resource_type"], "title": "ProjectPlannedResourceSetItemCreate", "type": "object"}, "ProjectPlannedResourceSetItemUpdate": {"additionalProperties": false, "description": "Schema for updating a ProjectPlannedResourceSetItem.", "properties": {"resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource ID", "title": "Resource Id"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource type (ROBOT or TECHNICIAN)", "title": "Resource Type"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Project Location Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start date", "title": "Start Date"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End date", "title": "End Date"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ProjectPlannedResourceSetStatus"}, {"type": "null"}], "description": "Approval lifecycle status"}}, "title": "ProjectPlannedResourceSetItemUpdate", "type": "object"}, "ProjectPlannedResourceSetItemCommitmentQueryParams": {"additionalProperties": false, "description": "Query parameters for the planned scope commitments endpoint.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by service", "title": "Service Id"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by pricing unit", "title": "Pricing Unit Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine model", "title": "Turbine Model Id"}}, "title": "ProjectPlannedResourceSetItemCommitmentQueryParams", "type": "object"}, "ProjectPlannedResourceSetItemCommitmentResponse": {"additionalProperties": false, "description": "Schema for planned scope commitment response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Commitment ID", "title": "Id", "type": "integer"}, "project_planned_resource_set_item_id": {"description": "Deployment leg (planned resource set item) ID", "title": "Project Planned Resource Set Item Id", "type": "integer"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}], "description": "Committed quantity", "title": "Quantity"}, "service": {"$ref": "#/components/schemas/ServiceObject", "description": "Committed service"}, "pricing_unit": {"$ref": "#/components/schemas/PricingUnitNestedResponse", "description": "Unit the quantity is expressed in"}, "turbine_model": {"anyOf": [{"$ref": "#/components/schemas/TurbineModelObject"}, {"type": "null"}], "description": "Turbine model the commitment is specific to, if any"}}, "required": ["updated_at", "id", "project_planned_resource_set_item_id", "quantity", "service", "pricing_unit"], "title": "ProjectPlannedResourceSetItemCommitmentResponse", "type": "object"}, "ProjectPlannedResourceSetItemCommitmentCreate": {"additionalProperties": false, "description": "Schema for creating a planned scope commitment on a deployment leg.", "properties": {"service_id": {"description": "Service ID", "title": "Service Id", "type": "integer"}, "pricing_unit_id": {"description": "Pricing unit (the unit) ID", "title": "Pricing Unit Id", "type": "integer"}, "quantity": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "string"}], "description": "Committed quantity", "title": "Quantity"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Optional turbine model the commitment is specific to", "title": "Turbine Model Id"}}, "required": ["service_id", "pricing_unit_id", "quantity"], "title": "ProjectPlannedResourceSetItemCommitmentCreate", "type": "object"}, "ProjectPlannedResourceSetItemCommitmentUpdate": {"additionalProperties": false, "description": "Schema for updating a planned scope commitment.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pricing unit (the unit) ID", "title": "Pricing Unit Id"}, "quantity": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Committed quantity", "title": "Quantity"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Optional turbine model the commitment is specific to", "title": "Turbine Model Id"}}, "title": "ProjectPlannedResourceSetItemCommitmentUpdate", "type": "object"}, "ProjectReadinessBucket": {"additionalProperties": false, "description": "Readiness tally for tasks not tied to any planned resource set.", "properties": {"total": {"title": "Total", "type": "integer"}, "completed": {"title": "Completed", "type": "integer"}}, "required": ["total", "completed"], "title": "ProjectReadinessBucket", "type": "object"}, "ProjectReadinessResponse": {"additionalProperties": false, "description": "Per-set + project-wide readiness tallies.", "properties": {"sets": {"items": {"$ref": "#/components/schemas/ProjectReadinessSetTally"}, "title": "Sets", "type": "array"}, "project_wide": {"$ref": "#/components/schemas/ProjectReadinessBucket"}}, "required": ["sets", "project_wide"], "title": "ProjectReadinessResponse", "type": "object"}, "ProjectReadinessSetTally": {"additionalProperties": false, "description": "Readiness tally for a single planned resource set.", "properties": {"planned_resource_set_id": {"title": "Planned Resource Set Id", "type": "integer"}, "total": {"title": "Total", "type": "integer"}, "completed": {"title": "Completed", "type": "integer"}}, "required": ["planned_resource_set_id", "total", "completed"], "title": "ProjectReadinessSetTally", "type": "object"}, "BusinessTravelOrderListSchema": {"additionalProperties": false, "description": "Schema for business travel order list response.", "properties": {"id": {"description": "BTO database ID", "title": "Id", "type": "integer"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Planned start date", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Planned end date", "title": "End Date"}, "robot_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set information", "title": "Robot Set"}, "service_by_robotic_set": {"description": "Service code that will be handled by robotic set", "title": "Service By Robotic Set", "type": "string"}, "status": {"description": "Delivery status of BTO emails", "title": "Status", "type": "string"}}, "required": ["id", "service_by_robotic_set", "status"], "title": "BusinessTravelOrderListSchema", "type": "object"}, "BusinessTravelOrderCreateSchema": {"additionalProperties": false, "description": "Schema for business travel order creation.", "properties": {"service_id": {"description": "CORE Service ID", "title": "Service Id", "type": "integer"}, "project_location_id": {"description": "CORE ProjectLocation ID the service is delivered at", "title": "Project Location Id", "type": "integer"}, "project_resource_set_id": {"description": "CORE ProjectResourceSet ID to populate team members", "title": "Project Resource Set Id", "type": "integer"}, "supervisor_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Django auth User ID for the BTO supervisor", "title": "Supervisor User Id"}}, "required": ["service_id", "project_location_id", "project_resource_set_id"], "title": "BusinessTravelOrderCreateSchema", "type": "object"}, "BusinessTravelOrderAuditUser": {"additionalProperties": false, "description": "Schema describing a user involved in BTO lifecycle events.", "properties": {"full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full name of the user", "title": "Full Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address of the user", "title": "Email"}}, "title": "BusinessTravelOrderAuditUser", "type": "object"}, "BusinessTravelOrderDetailSchema": {"description": "Schema for business travel order details.\n\nBusiness travel order is sent by specific set on specific service.", "properties": {"project_technical_information": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Link to folder for technical information", "title": "Project Technical Information"}, "project_technical_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Technical description text field", "title": "Project Technical Description"}, "daily_report_folder_link": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Google Drive daily report folder link", "title": "Daily Report Folder Link"}, "robot_set_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set id in specific project", "title": "Robot Set Id"}, "resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource set ID from CORE schema", "title": "Resource Set Id"}, "id": {"description": "BTO database ID", "title": "Id", "type": "integer"}, "team_members": {"anyOf": [{"items": {"$ref": "#/components/schemas/TeamMember"}, "type": "array"}, {"type": "null"}], "description": "List of team members assigned to the BTO and receiving emails", "title": "Team Members"}, "robot_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set name (code)", "title": "Robot Set"}, "units_total": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Total units, prefilled from assets but editable", "title": "Units Total"}, "units_turbines": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Total turbines", "title": "Units Turbines"}, "units_blades": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Total blades", "title": "Units Blades"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Planned project start date", "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Planned project end date", "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Actual start date", "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Actual end date", "title": "Actual End Date"}, "dedicated_client_scope_change": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Dedicated client for scope change (LER projects only)", "title": "Dedicated Client Scope Change"}, "reinspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Reinspection information", "title": "Reinspection"}, "status": {"$ref": "#/components/schemas/TravelOrderStatus", "description": "Delivery status of BTO emails"}, "prejob_pdf": {"description": "Pre-job PDF link", "title": "Prejob Pdf", "type": "string"}, "questionnaire_filled": {"default": 0, "description": "BTO questionnaire filled by team lead 0-100", "title": "Questionnaire Filled", "type": "integer"}, "service_category_by_robotic_set": {"description": "Code of service category.", "title": "Service Category By Robotic Set", "type": "string"}, "service_name_by_robotic_set": {"description": "Service name", "title": "Service Name By Robotic Set", "type": "string"}, "service_by_robotic_set": {"description": "Service code by robotic set", "title": "Service By Robotic Set", "type": "string"}, "site_contact_persons": {"default": [], "description": "List of site contact persons", "items": {"$ref": "#/components/schemas/ContactPerson"}, "title": "Site Contact Persons", "type": "array"}, "site_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site name", "title": "Site Name"}, "site_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site address", "title": "Site Address"}, "site_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Site latitude", "title": "Site Latitude"}, "site_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Site longitude", "title": "Site Longitude"}, "site_country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site country, two letter ISO code", "title": "Site Country"}, "om_building_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "O&M building address", "title": "Om Building Address"}, "om_building_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "O&M building latitude", "title": "Om Building Latitude"}, "om_building_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "O&M building longitude", "title": "Om Building Longitude"}, "can_compensate_on_sundays": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether work on Sundays can be compensated, taken from site safety form", "title": "Can Compensate On Sundays"}, "can_work_six_days": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether work on six days a week is allowed, taken from site safety form", "title": "Can Work Six Days"}, "regional_or_country_regulations": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Regional or country-specific regulations affecting work schedules, taken from site safety form", "title": "Regional Or Country Regulations"}, "operational_limitations": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Operational limitations affecting work schedules, taken from site safety form", "title": "Operational Limitations"}, "team_from_iep": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "default": false, "description": "Whether team members were populated from IEP resource set", "title": "Team From Iep"}, "created_by": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderAuditUser"}, {"type": "null"}], "description": "Information about who created the BTO"}, "sent_by": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderAuditUser"}, {"type": "null"}], "description": "Information about who sent the BTO notifications"}}, "required": ["id", "status", "prejob_pdf", "service_category_by_robotic_set", "service_name_by_robotic_set", "service_by_robotic_set"], "title": "BusinessTravelOrderDetailSchema", "type": "object"}, "ContactPerson": {"additionalProperties": false, "description": "Schema for contact person.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full name of the contact person.", "title": "Name"}, "email": {"anyOf": [{"format": "email", "type": "string"}, {"type": "null"}], "description": "Valid email address of the contact person.", "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Role of the contact person (for site contacts)", "title": "Role"}}, "title": "ContactPerson", "type": "object"}, "TeamMember": {"description": "Schema for Aerones team member.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"format": "email", "type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}, "qualifications": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "List of qualifications for the team member.", "title": "Qualifications"}}, "title": "TeamMember", "type": "object"}, "TravelOrderStatus": {"description": "Travel order status.", "enum": ["Draft", "Sent"], "title": "TravelOrderStatus", "type": "string"}, "BusinessTravelOrderUpdateSchema": {"additionalProperties": false, "description": "Schema for business travel order updates.", "properties": {"project_technical_information": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Link to folder for technical information", "title": "Project Technical Information"}, "project_technical_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Technical description text field", "title": "Project Technical Description"}, "daily_report_folder_link": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Google Drive daily report folder link", "title": "Daily Report Folder Link"}, "robot_set_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set id in specific project", "title": "Robot Set Id"}, "resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resource set ID from CORE schema", "title": "Resource Set Id"}, "supervisor_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Django auth User ID for the BTO supervisor", "title": "Supervisor User Id"}}, "title": "BusinessTravelOrderUpdateSchema", "type": "object"}, "BusinessTravelOrderBCLQuestionsSchema": {"additionalProperties": false, "description": "BCL specific questions.", "properties": {"water_source_identification": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know where to take the water from."}, "chemical_availability": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have the required chemicals with me, and I know exactly which ones they are and how to use them."}, "dirtiness_assessment": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know the type and level of dirtiness on the WTG."}}, "title": "BusinessTravelOrderBCLQuestionsSchema", "type": "object"}, "BusinessTravelOrderICEQuestionsSchema": {"additionalProperties": false, "description": "ICE specific questions.", "properties": {"ensure_internet_cables": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Ensure internet cables have the correct connectors."}, "confirm_ice_chemicals": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Confirm that enough ICE chemicals are in stock."}, "verify_spare_motor": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Verify that a spare motor is available for the cleaning robot."}, "curing_time_source": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What is the curing time for the material?"}, "repeat_photos_understanding": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand that repeat photos must be taken 24 hours after the curing time."}}, "title": "BusinessTravelOrderICEQuestionsSchema", "type": "object"}, "BusinessTravelOrderIINOFSQuestionsSchema": {"additionalProperties": false, "description": "IIN-OFS specific questions.", "properties": {"specific_customer_requirements": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand the specific customer requirements for the inspection."}, "crawler_operation_requirements": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand the minimum crawler operation requirements for performing the service."}, "crawler_spare_parts_availability": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am aware of the availability of crawler spare parts during the turbine service."}, "data_upload_familiarity": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have access to the data upload folders and am familiar with data sorting."}, "blade_information_card_familiarity": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am familiar with the blade information card and its purpose."}, "data_upload_timing": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand that data uploads must be completed within 24 hours."}, "gas_detector_expiry_awareness": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I acknowledge that the gas detector expiry date must not be less than two months."}, "quick_spare_parts_awareness": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am aware of the quick availability of critical spare parts at the offshore site"}, "starlink_offshore_availability": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Starlink for offshore use is available in the set."}}, "title": "BusinessTravelOrderIINOFSQuestionsSchema", "type": "object"}, "BusinessTravelOrderIINONSQuestionsSchema": {"additionalProperties": false, "description": "IIN-ONS specific questions.", "properties": {"specific_customer_requirements": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand the specific customer requirements for the inspection."}, "crawler_operation_requirements": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand the minimum crawler operation requirements for performing the service."}, "crawler_spare_parts_availability": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am aware of the availability of crawler spare parts during the turbine service."}, "data_upload_familiarity": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have access to the data upload folders and am familiar with data sorting."}, "blade_information_card_familiarity": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am familiar with the blade information card and its purpose."}, "data_upload_timing": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I understand that data uploads must be completed within 24 hours."}, "gas_detector_expiry_awareness": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I acknowledge that the gas detector expiry date must not be less than two months."}}, "title": "BusinessTravelOrderIINONSQuestionsSchema", "type": "object"}, "BusinessTravelOrderLERQuestionsSchema": {"additionalProperties": false, "description": "LER specific questions.", "properties": {"robotic_tools_in_use": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "How many robotic tools are in use, and what types are they?"}, "robotic_tool_usage_sequence": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What is the sequence of robotic tool usage?"}, "project_materials": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What materials will be used in this project?"}, "drone_photo_activities": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "After which activities must photos be taken with a drone?"}, "ler_meters": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "How many meters of LER will be performed?"}, "scope_change_definition": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What does \"scope change\" mean?"}, "material_curing_time_source": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Where can the curing time for each material be found?"}}, "title": "BusinessTravelOrderLERQuestionsSchema", "type": "object"}, "BusinessTravelOrderLPSQuestionsSchema": {"additionalProperties": false, "description": "LPS specific questions.", "properties": {"receptor_types_known": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Is the number and location of receptors on the blade known?"}, "bridge_necessity_known": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Is the bridge necessary, and in what cases is it used?"}, "blade_troubleshooting_known": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Do you know how to troubleshoot a blade?"}, "service_provided_known": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Do you know what service are you providing?"}, "full_loop_measurements_required": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Does the client require full loop measurements or blade-only measurements?"}}, "title": "BusinessTravelOrderLPSQuestionsSchema", "type": "object"}, "BusinessTravelOrderQuestionsGeneralSchema": {"additionalProperties": false, "description": "General questions applicable to any business travel order.", "properties": {"proper_rescue_device": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have the proper rescue device and know how to inspect it."}, "fall_arrester": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have the proper fall arrester. (What type of fall arrester is required?)"}, "jsa_completion": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to complete the JSA and understand the criteria for filling it out."}, "ppe_inspection": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to inspect PPE and check expiration dates."}, "car_incident_action": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to act in the event of a car incident."}, "hot_weather_action": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to act in extremely hot weather conditions."}, "data_sheets_available": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have the relevant data sheets available."}, "near_miss_response": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to respond to a near miss and how to report it."}, "health_compliance_action": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to act in health compliance situations."}, "insurance_policy_info": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have been informed about the insurance policy."}, "turbine_models_info": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am aware of the turbine models scheduled for service."}, "wtg_operation": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to operate the WTG."}, "wtg_list_available": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "A list of WTGs requiring servicing is available."}, "maintainx_access": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have access to MaintainX and am added to the correct set."}, "maintainx_set_acceptance": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to perform set acceptance in MaintainX."}, "maintainx_support": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am familiar with using MaintainX for support."}, "purchase_order_creation": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to create a purchase order."}, "set_not_working_procedure": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know what to do if, upon set acceptance, the set is found not to be in working order."}, "spendesk_access": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have access to a Spendesk card and know how to report expenses"}, "work_hours_registration": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to register work hours."}, "vehicle_form_info": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I am aware of how to fill out the vehicle acceptance and transfer form."}, "accommodation_request": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know how to request accommodation."}, "site_address_info": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have the site address and the contact person's phone number."}}, "title": "BusinessTravelOrderQuestionsGeneralSchema", "type": "object"}, "BusinessTravelOrderQuestionsSchema": {"additionalProperties": false, "description": "Schema for BTO questionnaire (both read and write operations).", "properties": {"general": {"$ref": "#/components/schemas/BusinessTravelOrderQuestionsGeneralSchema", "description": "General questions applicable to any business travel order"}, "iin_ons": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderIINONSQuestionsSchema"}, {"type": "null"}], "description": "IIN-ONS specific questions, included only if BTO is for IIN-ONS service"}, "iin_ofs": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderIINOFSQuestionsSchema"}, {"type": "null"}], "description": "IIN-OFS specific questions, included only if BTO is for IIN-OFS service"}, "ler": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderLERQuestionsSchema"}, {"type": "null"}], "description": "LER specific questions, included only if BTO is for LER service"}, "tcl": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderTCLQuestionsSchema"}, {"type": "null"}], "description": "TCL specific questions, included only if BTO is for TCL service"}, "bcl": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderBCLQuestionsSchema"}, {"type": "null"}], "description": "BCL specific questions, included only if BTO is for BCL service"}, "vin": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderVINQuestionsSchema"}, {"type": "null"}], "description": "VIN specific questions, included only if BTO is for VIN service"}, "lps": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderLPSQuestionsSchema"}, {"type": "null"}], "description": "LPS specific questions, included only if BTO is for LPS service"}, "rat": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderRATQuestionsSchema"}, {"type": "null"}], "description": "RAT specific questions, included only if BTO is for RAT service"}, "ice": {"anyOf": [{"$ref": "#/components/schemas/BusinessTravelOrderICEQuestionsSchema"}, {"type": "null"}], "description": "ICE specific questions, included only if BTO is for ICE service"}}, "required": ["general"], "title": "BusinessTravelOrderQuestionsSchema", "type": "object"}, "BusinessTravelOrderRATQuestionsSchema": {"additionalProperties": false, "description": "RAT specific questions.", "properties": {"safety_devices_required": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "How many ASAP safety devices are required for the work?"}, "deviation_definition": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What is a deviation?"}, "nacelle_access_equipment": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What equipment will be used to access the bottom of the nacelle?"}, "deviation_equipment": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "What equipment will be used for deviation?"}}, "title": "BusinessTravelOrderRATQuestionsSchema", "type": "object"}, "BusinessTravelOrderTCLQuestionsSchema": {"additionalProperties": false, "description": "TCL specific questions.", "properties": {"water_source_identification": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know where to take the water from."}, "chemical_availability": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I have the required chemicals with me, and I know exactly which ones they are and how to use them."}, "dirtiness_assessment": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "I know the type and level of dirtiness on the WTG."}, "wastewater_disposal_known": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "If necessary, I know where to dispose of the wastewater."}}, "title": "BusinessTravelOrderTCLQuestionsSchema", "type": "object"}, "BusinessTravelOrderVINQuestionsSchema": {"additionalProperties": false, "description": "VIN specific questions.", "properties": {"flight_restrictions": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Are there any flight restrictions or airports nearby?"}, "charging_socket_info": {"anyOf": [{"$ref": "#/components/schemas/QuestionField"}, {"type": "null"}], "description": "Does the tower have a socket for charging batteries, and does it require an adapter?"}}, "title": "BusinessTravelOrderVINQuestionsSchema", "type": "object"}, "QuestionField": {"additionalProperties": false, "description": "Schema for a single question field with checkbox and description.", "properties": {"is_checked": {"default": false, "description": "Whether the question is marked as known/understood (I know / I don't know)", "title": "Is Checked", "type": "boolean"}, "description": {"default": "", "description": "Optional freeform text field for additional details", "title": "Description", "type": "string"}}, "title": "QuestionField", "type": "object"}, "QuestionnaireRecipientResponse": {"additionalProperties": false, "description": "Per-member email/questionnaire tracking for the roster's Email column.\n\nOnly present for crew members provisioned a questionnaire row, which\nhappens at send. `questionnaire_id` is the crew's stable magic-link UUID so\nstaff can open or copy the crew URL; `events` is the append-only timeline\nthe popover renders.", "properties": {"questionnaire_id": {"title": "Questionnaire Id", "type": "string"}, "resource_id": {"title": "Resource Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "sent_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sent At"}, "opened_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Opened At"}, "events": {"default": [], "items": {"type": "object"}, "title": "Events", "type": "array"}}, "required": ["questionnaire_id", "resource_id"], "title": "QuestionnaireRecipientResponse", "type": "object"}, "SiteContactResponse": {"additionalProperties": false, "description": "One Pre-Job site contact for the internal set panel's contacts table.\n\nSame shape as the crew payload's contact rows. Sourced per project-location\nfrom the Pre-Job composite (see `TravelOrderManager.site_contacts`).", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}}, "title": "SiteContactResponse", "type": "object"}, "SupervisorResponse": {"additionalProperties": false, "description": "One assigned supervisor (an OpsHub user) for the supervisors panel chips.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}}, "required": ["id", "name"], "title": "SupervisorResponse", "type": "object"}, "TeamMemberResponse": {"additionalProperties": false, "properties": {"resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}, "qualifications": {"default": [], "items": {"type": "string"}, "title": "Qualifications", "type": "array"}, "is_lead": {"default": false, "title": "Is Lead", "type": "boolean"}, "membership_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Membership Status"}, "joined_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Joined At"}, "removed_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Removed At"}}, "title": "TeamMemberResponse", "type": "object"}, "TravelOrderResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"title": "Project Id", "type": "integer"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "location_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Location Latitude"}, "location_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Location Longitude"}, "location_country": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Country"}, "resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Set Id"}, "resource_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Set Name"}, "resource_set_robot_names": {"default": [], "items": {"type": "string"}, "title": "Resource Set Robot Names", "type": "array"}, "resource_set_from_planned": {"default": false, "title": "Resource Set From Planned", "type": "boolean"}, "resource_set_deleted": {"default": false, "title": "Resource Set Deleted", "type": "boolean"}, "service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "status": {"title": "Status", "type": "string"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "mobilization_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Mobilization Date"}, "send_blockers": {"default": [], "items": {"type": "string"}, "title": "Send Blockers", "type": "array"}, "team_members": {"items": {"$ref": "#/components/schemas/TeamMemberResponse"}, "title": "Team Members", "type": "array"}, "supervisor_user_ids": {"items": {"type": "integer"}, "title": "Supervisor User Ids", "type": "array"}, "supervisors": {"default": [], "items": {"$ref": "#/components/schemas/SupervisorResponse"}, "title": "Supervisors", "type": "array"}, "questionnaires": {"default": [], "items": {"$ref": "#/components/schemas/QuestionnaireRecipientResponse"}, "title": "Questionnaires", "type": "array"}, "site_contacts": {"default": [], "items": {"$ref": "#/components/schemas/SiteContactResponse"}, "title": "Site Contacts", "type": "array"}, "drive_folder_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Drive Folder Url"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "is_archived": {"default": false, "title": "Is Archived", "type": "boolean"}, "created_at": {"title": "Created At", "type": "string"}, "units_turbines": {"title": "Units Turbines", "type": "integer"}, "units_blades": {"title": "Units Blades", "type": "integer"}, "units_total": {"title": "Units Total", "type": "integer"}, "set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Set Name"}, "bto_creator": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Bto Creator"}, "bto_sender": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Bto Sender"}, "scope_change_contact": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Scope Change Contact"}, "reinspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Reinspection"}, "gate_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Gate Latitude"}, "gate_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Gate Longitude"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "om_building_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Om Building Address"}, "om_building_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Om Building Latitude"}, "om_building_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Om Building Longitude"}, "allowed_six_days": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Allowed Six Days"}, "compensate_idle_sundays": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Compensate Idle Sundays"}, "regional_regulations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Regional Regulations"}, "operational_limitations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Operational Limitations"}, "offer_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Offer Status"}, "updated_at": {"title": "Updated At", "type": "string"}}, "required": ["id", "project_id", "service_id", "service_code", "status", "team_members", "supervisor_user_ids", "created_at", "units_turbines", "units_blades", "units_total", "updated_at"], "title": "TravelOrderResponse", "type": "object"}, "TravelOrderCreateSchema": {"additionalProperties": false, "properties": {"project_location_id": {"title": "Project Location Id", "type": "integer"}, "resource_set_id": {"title": "Resource Set Id", "type": "integer"}, "service_id": {"title": "Service Id", "type": "integer"}, "supervisor_user_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Supervisor User Ids"}, "drive_folder_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Drive Folder Url"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}}, "required": ["project_location_id", "resource_set_id", "service_id"], "title": "TravelOrderCreateSchema", "type": "object"}, "TravelOrderUpdateSchema": {"additionalProperties": false, "properties": {"project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Set Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "supervisor_user_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Supervisor User Ids"}, "drive_folder_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Drive Folder Url"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "title": "TravelOrderUpdateSchema", "type": "object"}, "ResendResult": {"additionalProperties": false, "properties": {"resource_id": {"title": "Resource Id", "type": "integer"}, "ok": {"title": "Ok", "type": "boolean"}}, "required": ["resource_id", "ok"], "title": "ResendResult", "type": "object"}, "CategoryStatusResponse": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}, "status": {"title": "Status", "type": "string"}}, "required": ["name", "status"], "title": "CategoryStatusResponse", "type": "object"}, "MemberProgressResponse": {"additionalProperties": false, "properties": {"resource_id": {"title": "Resource Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "role": {"title": "Role", "type": "string"}, "answered": {"title": "Answered", "type": "integer"}, "total": {"title": "Total", "type": "integer"}, "flagged": {"title": "Flagged", "type": "integer"}, "categories": {"default": [], "items": {"$ref": "#/components/schemas/CategoryStatusResponse"}, "title": "Categories", "type": "array"}}, "required": ["resource_id", "name", "role", "answered", "total", "flagged"], "title": "MemberProgressResponse", "type": "object"}, "QuestionAnswerResponse": {"additionalProperties": false, "properties": {"key": {"title": "Key", "type": "string"}, "category_name": {"title": "Category Name", "type": "string"}, "text": {"title": "Text", "type": "string"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Value"}, "note": {"default": "", "title": "Note", "type": "string"}}, "required": ["key", "category_name", "text"], "title": "QuestionAnswerResponse", "type": "object"}, "SubmitAnswerSchema": {"additionalProperties": false, "properties": {"value": {"$ref": "#/components/schemas/TravelOrderAnswerValue"}, "note": {"default": "", "title": "Note", "type": "string"}}, "required": ["value"], "title": "SubmitAnswerSchema", "type": "object"}, "TravelOrderAnswerValue": {"description": "Canonical answer values, stored lowercase in the answers JSONB to match\nthe design ids (`yes` | `no` | `need_info`).", "enum": ["yes", "no", "need_info"], "title": "TravelOrderAnswerValue", "type": "string"}, "CrewAnswerSchema": {"additionalProperties": false, "properties": {"key": {"title": "Key", "type": "string"}, "category_name": {"title": "Category Name", "type": "string"}, "text": {"title": "Text", "type": "string"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Value"}, "note": {"default": "", "title": "Note", "type": "string"}}, "required": ["key", "category_name", "text"], "title": "CrewAnswerSchema", "type": "object"}, "CrewContactSchema": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}}, "title": "CrewContactSchema", "type": "object"}, "CrewMemberSchema": {"additionalProperties": false, "properties": {"resource_id": {"title": "Resource Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}}, "required": ["resource_id"], "title": "CrewMemberSchema", "type": "object"}, "CrewOverviewResponse": {"additionalProperties": false, "description": "Self-contained payload the crew page renders from a single UUID GET.\n\nOrder essentials + the visitor's own identity + their questionnaire +\nread-only overview (site contacts, the frozen team roster). No staff-only\ndata, no project-scoped IDs the crew could edit.\n\nThe overview-card fields below are the crew-safe, read-only projection of\nthe same sources the staff detail (`bto/api/travel_orders.py`) uses -- so\nthe crew page's six overview cards match the staff view 1-to-1 rather than\ndegrading to \"Not set\". Every field is null-safe: a source with no Core\nhome yet returns null and the UI renders \"Not set\".", "properties": {"questionnaire_id": {"title": "Questionnaire Id", "type": "string"}, "travel_order_id": {"title": "Travel Order Id", "type": "integer"}, "member_removed": {"default": false, "title": "Member Removed", "type": "boolean"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "service_code": {"title": "Service Code", "type": "string"}, "location_name": {"title": "Location Name", "type": "string"}, "location_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Location Latitude"}, "location_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Location Longitude"}, "location_country": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Country"}, "planned_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "mobilization_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Mobilization Date"}, "drive_folder_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Drive Folder Url"}, "member": {"$ref": "#/components/schemas/CrewMemberSchema"}, "team_members": {"default": [], "items": {"$ref": "#/components/schemas/CrewMemberSchema"}, "title": "Team Members", "type": "array"}, "site_contacts": {"default": [], "items": {"$ref": "#/components/schemas/CrewContactSchema"}, "title": "Site Contacts", "type": "array"}, "questionnaire": {"default": [], "items": {"$ref": "#/components/schemas/CrewAnswerSchema"}, "title": "Questionnaire", "type": "array"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Name"}, "project_manager": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Manager"}, "sales_account_executive": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sales Account Executive"}, "bto_creator": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Bto Creator"}, "bto_sender": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Bto Sender"}, "set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Set Name"}, "units_turbines": {"default": 0, "title": "Units Turbines", "type": "integer"}, "units_blades": {"default": 0, "title": "Units Blades", "type": "integer"}, "units_total": {"default": 0, "title": "Units Total", "type": "integer"}, "supervisor_names": {"default": [], "items": {"type": "string"}, "title": "Supervisor Names", "type": "array"}, "actual_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "scope_change_contact": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Scope Change Contact"}, "reinspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Reinspection"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "om_building_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Om Building Address"}, "om_building_latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Om Building Latitude"}, "om_building_longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Om Building Longitude"}, "allowed_six_days": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Allowed Six Days"}, "compensate_idle_sundays": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Compensate Idle Sundays"}, "regional_regulations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Regional Regulations"}, "operational_limitations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Operational Limitations"}}, "required": ["questionnaire_id", "travel_order_id", "service_code", "location_name", "member"], "title": "CrewOverviewResponse", "type": "object"}, "CrewSubmitAnswerSchema": {"additionalProperties": false, "properties": {"value": {"$ref": "#/components/schemas/TravelOrderAnswerValue"}, "note": {"default": "", "title": "Note", "type": "string"}}, "required": ["value"], "title": "CrewSubmitAnswerSchema", "type": "object"}, "CommunicationAttachment": {"additionalProperties": false, "description": "A file attached to a communication note or task comment.", "properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "file_name": {"title": "File Name", "type": "string"}, "file_type": {"title": "File Type", "type": "string"}}, "required": ["id", "file_name", "file_type"], "title": "CommunicationAttachment", "type": "object"}, "CommunicationUser": {"additionalProperties": false, "description": "Lightweight user reference used in communication payloads.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}}, "required": ["id", "name"], "title": "CommunicationUser", "type": "object"}, "ProjectCommentResponse": {"additionalProperties": false, "description": "A single project communication note.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "body": {"title": "Body", "type": "string"}, "body_format": {"default": "text", "title": "Body Format", "type": "string"}, "author": {"anyOf": [{"$ref": "#/components/schemas/CommunicationUser"}, {"type": "null"}]}, "edited_by": {"anyOf": [{"$ref": "#/components/schemas/CommunicationUser"}, {"type": "null"}], "description": "User who last updated the comment (domain rename of updated_by)."}, "is_edited": {"default": false, "description": "Whether the comment was edited after it was created.", "title": "Is Edited", "type": "boolean"}, "mentioned_users": {"items": {"$ref": "#/components/schemas/CommunicationUser"}, "title": "Mentioned Users", "type": "array"}, "attachments": {"items": {"$ref": "#/components/schemas/CommunicationAttachment"}, "title": "Attachments", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["updated_at", "id", "body", "created_at"], "title": "ProjectCommentResponse", "type": "object"}, "ProjectCommentCreate": {"additionalProperties": false, "description": "Create a project communication note.", "properties": {"body": {"description": "Note body.", "minLength": 1, "title": "Body", "type": "string"}, "body_format": {"default": "text", "description": "How `body` is encoded.", "enum": ["text", "markdown"], "title": "Body Format", "type": "string"}, "mentioned_user_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "User ids @-mentioned in the note. Ignored for body_format='markdown' \u2014 mentions are parsed from the body instead.", "title": "Mentioned User Ids"}, "attachment_file_ids": {"anyOf": [{"items": {"format": "uuid", "type": "string"}, "type": "array"}, {"type": "null"}], "description": "Storage ids of files attached to the note.", "title": "Attachment File Ids"}}, "required": ["body"], "title": "ProjectCommentCreate", "type": "object"}, "ProjectCommentUpdate": {"additionalProperties": false, "description": "Edit a project communication note (author only).", "properties": {"body": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Note body.", "title": "Body"}, "body_format": {"anyOf": [{"enum": ["text", "markdown"], "type": "string"}, {"type": "null"}], "description": "How `body` is encoded.", "title": "Body Format"}, "mentioned_user_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Replacement mention set. None leaves it untouched, [] clears. Ignored for body_format='markdown'.", "title": "Mentioned User Ids"}, "attachment_file_ids": {"anyOf": [{"items": {"format": "uuid", "type": "string"}, "type": "array"}, {"type": "null"}], "description": "Replacement attachment set. None leaves it untouched, [] clears.", "title": "Attachment File Ids"}}, "title": "ProjectCommentUpdate", "type": "object"}, "CommunicationFeedEntry": {"additionalProperties": false, "description": "A unified feed entry \u2014 a project note or a surfaced task comment.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "kind": {"enum": ["message", "task_comment"], "title": "Kind", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "body": {"title": "Body", "type": "string"}, "body_format": {"default": "text", "title": "Body Format", "type": "string"}, "author": {"anyOf": [{"$ref": "#/components/schemas/CommunicationUser"}, {"type": "null"}]}, "edited_by": {"anyOf": [{"$ref": "#/components/schemas/CommunicationUser"}, {"type": "null"}], "description": "User who last updated the comment (domain rename of updated_by)."}, "is_edited": {"default": false, "description": "Whether the comment was edited after it was created.", "title": "Is Edited", "type": "boolean"}, "mentioned_users": {"items": {"$ref": "#/components/schemas/CommunicationUser"}, "title": "Mentioned Users", "type": "array"}, "attachments": {"items": {"$ref": "#/components/schemas/CommunicationAttachment"}, "title": "Attachments", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "task_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Set for task_comment entries \u2014 the source task id.", "title": "Task Id"}, "task_title": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Set for task_comment entries \u2014 the source task title.", "title": "Task Title"}}, "required": ["updated_at", "kind", "id", "body", "created_at"], "title": "CommunicationFeedEntry", "type": "object"}, "MentionCandidate": {"additionalProperties": false, "description": "One user available for @-mention in a Set Request note.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}}, "required": ["id", "name"], "title": "MentionCandidate", "type": "object"}, "RoleMemberListResponse": {"additionalProperties": false, "description": "The people a role mention notifies, for the reader-facing role chip.\n\nReuses ``MentionCandidate`` so one shape describes a person in the picker\nand in this list. ``total`` is the whole role; ``members`` is one page.", "properties": {"members": {"items": {"$ref": "#/components/schemas/MentionCandidate"}, "title": "Members", "type": "array"}, "total": {"default": 0, "title": "Total", "type": "integer"}, "has_more": {"default": false, "title": "Has More", "type": "boolean"}}, "required": ["members"], "title": "RoleMemberListResponse", "type": "object"}, "MentionCandidateListResponse": {"additionalProperties": false, "properties": {"candidates": {"items": {"$ref": "#/components/schemas/MentionCandidate"}, "title": "Candidates", "type": "array"}}, "title": "MentionCandidateListResponse", "type": "object"}, "ProjectScopeChangeRequestQueryParams": {"additionalProperties": false, "description": "Query parameters for ProjectScopeChangeRequest list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search in description", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "project_offer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project offer ID", "title": "Project Offer Id"}, "type": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestType"}, {"type": "null"}], "description": "Filter by type"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestStatus"}, {"type": "null"}], "description": "Filter by approval status (incl. REJECTED)"}}, "title": "ProjectScopeChangeRequestQueryParams", "type": "object"}, "ProjectScopeChangeRequestStatus": {"description": "Approval-flow statuses for scope change requests.", "enum": ["WAITING_FOR_QC", "WAITING_FOR_SALES", "WAITING_FOR_PM", "APPROVED", "REJECTED"], "title": "ProjectScopeChangeRequestStatus", "type": "string"}, "ProjectScopeChangeRequestType": {"description": "Enum for project scope change types.", "enum": ["service_change_severity", "client_cancel_service", "asset_swap", "client_decrease_scope"], "title": "ProjectScopeChangeRequestType", "type": "string"}, "ProjectScopeChangeRequestCustomFieldsOut": {"additionalProperties": true, "description": "Read-side twin of the custom-fields schema \u2014 must never 500 a GET.\n\n``custom_fields`` has no DB type constraint, so a legacy or\nhand-written row can violate the input contract the strict parent\nenforces on create. On serialization, malformed ids degrade to null\n(mirroring the regex-guarded SQL annotations that resolve the same\nkeys), unknown keys are surfaced as-is instead of failing the\nresponse model, and the condition sections loosen to bare dicts \u2014\nthe strict nested schemas would fail a GET over a hand-written row,\nand the UI parses the sections defensively anyway.", "properties": {"source_service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Source SOL id. Required when the scope change is a service replacement; must be paired with replacement_service_id.", "title": "Source Service Order Line Id"}, "source_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "TurbineComponent (blade) id the change applies to. Only meaningful on a service replacement whose source SOL covers the whole turbine (no pinned component): only the chosen blade's workorders move to the new SOL, and the source SOL stays active for the other blades. Omit (or null) to change the whole turbine \u2014 the source SOL is cancelled as before. On a blade-pinned source SOL the field must be absent or equal the pinned component.", "title": "Source Turbine Component Id"}, "replacement_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Replacement service id. Required when the scope change is a service replacement; must be paired with source_service_order_line_id.", "title": "Replacement Service Id"}, "evidence_file_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "core.File ids of evidence files previously uploaded via POST /api/core/v1/files. The backend creates a FileEntityLink row per id in the same transaction as the SCR; unknown ids cause the whole create to roll back with 422. The ids also persist in this JSON column as the historical input contract.", "title": "Evidence File Ids"}, "additional_workorders": {"anyOf": [{"items": {"$ref": "#/components/schemas/ScopeChangeAdditionalWorkorder"}, "type": "array"}, {"type": "null"}], "description": "Persisted copy of the top-level create field of the same name. The backend writes it here so a request that awaits QC \u2192 Sales \u2192 PM review still knows which workorders to generate when the finalize cascade eventually runs (possibly days after creation). Read-only in practice \u2014 supply the top-level create field instead of writing this key directly.", "title": "Additional Workorders"}, "initial_evaluation_condition": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Initial Evaluation Condition"}, "current_condition": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Current Condition"}}, "title": "ProjectScopeChangeRequestCustomFieldsOut", "type": "object"}, "ProjectScopeChangeRequestOrigin": {"description": "Which client created the scope change request.", "enum": ["AEROTASK", "OPSHUB"], "title": "ProjectScopeChangeRequestOrigin", "type": "string"}, "ProjectScopeChangeRequestResponse": {"additionalProperties": false, "description": "Schema for project scope change response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project scope change ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "project_offer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project offer ID", "title": "Project Offer Id"}, "type": {"description": "Type of scope change", "title": "Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Change description", "title": "Description"}, "custom_fields": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestCustomFieldsOut"}, {"type": "null"}], "description": "Scope-change metadata \u2014 same shape as on create. Unknown keys supplied by external clients are preserved and surfaced as-is; malformed id values degrade to null instead of failing the read."}, "replacement_service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Id of the replacement SOL created by this scope change. Only populated when the request is a service replacement; null for non-replacement types (e.g. client_decrease_scope) and on creates that didn't produce a new SOL. Lets clients jump straight to the new SOL without a second round trip.", "title": "Replacement Service Order Line Id"}, "source_service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code of the source SOL (the one named by custom_fields.source_service_order_line_id), e.g. 'LER-1-2'. Resolved server-side for table display so clients don't need a per-row SOL lookup. Null when the request has no source SOL.", "title": "Source Service Code"}, "source_service_order_line_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Current status of the source SOL (CANCELLED once a finalized scope change consumed it). Null without a source SOL.", "title": "Source Service Order Line Status"}, "replacement_service_order_line_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Current status of the replacement (new) SOL. Null until the finalize cascade created it.", "title": "Replacement Service Order Line Status"}, "source_turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine id of the source SOL. Null without a source SOL.", "title": "Source Turbine Id"}, "source_turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name of the source SOL. Null without a source SOL.", "title": "Source Turbine Name"}, "source_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "TurbineComponent id the change applies to: the source SOL's pinned component, or the requester-chosen blade (custom_fields.source_turbine_component_id) of a per-blade change on a whole-turbine SOL. Null means the change covers the whole turbine (or the request has no source SOL). This \u2014 not the position \u2014 is the authoritative component-vs-turbine-level signal.", "title": "Source Turbine Component Id"}, "source_turbine_component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade position (A/B/C) of the component the change applies to; null for whole-turbine changes and requests without a source SOL.", "title": "Source Turbine Component Position"}, "source_turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Serial number of the component the change applies to \u2014 the component's human identifier next to its position. Null for whole-turbine changes, requests without a source SOL, and components without a recorded serial.", "title": "Source Turbine Component Serial"}, "replacement_service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code of custom_fields.replacement_service_id, e.g. 'RAT'. Resolved server-side for table display. Null when the request has no replacement service.", "title": "Replacement Service Code"}, "cancelled_sol_workorder_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Workorder IDs on the source SOL that the scope change cancelled. Lets clients (e.g. AeroTask mobile) refresh only the affected workorders + handle soft-deletion locally instead of polling the whole workorder list. Only populated on the create response of a service-replacement scope change; null on non-replacement types and on read responses.", "title": "Cancelled Sol Workorder Ids"}, "new_sol_workorder_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Workorder IDs on the replacement SOL \u2014 both clones forwarded from the source SOL and any newly generated workorders from additional_workorders. Same refresh use case as cancelled_sol_workorder_ids. Only populated on the response of the call that ran the finalize cascade (create on auto-accept projects, the PM-stage approve otherwise); null on non-replacement types and on read responses.", "title": "New Sol Workorder Ids"}, "status": {"$ref": "#/components/schemas/ProjectScopeChangeRequestStatus", "description": "Approval status. Requests on auto-accept projects are APPROVED immediately at creation; others walk WAITING_FOR_QC \u2192 WAITING_FOR_SALES \u2192 WAITING_FOR_PM \u2192 APPROVED, or end REJECTED (terminal)."}, "initiated_from": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestOrigin"}, {"type": "null"}], "description": "Origin client (AEROTASK / OPSHUB). Null on legacy rows."}, "finalized_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the scope-change cascade actually ran. Null while the request awaits review, on rejected requests, and on non-replacement types (they have no cascade).", "title": "Finalized At"}, "created_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "User who created the request"}, "qc_approved_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "User who approved the QC stage"}, "qc_approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the QC stage was approved", "title": "Qc Approved At"}, "sales_approved_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "User who approved the Sales stage"}, "sales_approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the Sales stage was approved", "title": "Sales Approved At"}, "pm_approved_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "User who approved the PM stage"}, "pm_approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the PM stage was approved", "title": "Pm Approved At"}, "rejected_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "User who rejected the request"}, "rejected_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the request was rejected", "title": "Rejected At"}, "rejection_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Mandatory reason supplied on rejection (denormalized for table display; the audit copy lives in the status change log).", "title": "Rejection Reason"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}}, "required": ["updated_at", "id", "project_id", "type", "status", "created_at"], "title": "ProjectScopeChangeRequestResponse", "type": "object"}, "ScopeChangeAdditionalWorkorder": {"additionalProperties": false, "description": "One replacement-service ServiceItem to generate on the new SOL.\n\nEach entry includes a ServiceItem id and optionally a narrowed list of\nturbine components. ``service_item_id`` and ``turbine_component_ids``\nlive on the same level so there's no duplicated/parallel structure to\nkeep in sync.", "properties": {"service_item_id": {"description": "Replacement-service ServiceItem ID to generate as a NOT_STARTED workorder on the new SOL.", "title": "Service Item Id", "type": "integer"}, "turbine_component_ids": {"description": "TurbineComponent IDs that should receive a workorder for this ServiceItem. Each id must belong to the source SOL's turbine and match the ServiceItem's component type. Empty list = default selection (every matching component).", "items": {"type": "integer"}, "title": "Turbine Component Ids", "type": "array"}}, "required": ["service_item_id"], "title": "ScopeChangeAdditionalWorkorder", "type": "object"}, "ProjectScopeChangeRequestCreate": {"additionalProperties": false, "description": "Schema for creating a project scope change.\n\nThe service-replacement linkage (``source_service_order_line_id`` and\n``replacement_service_id``) and evidence file references\n(``evidence_file_ids``) live inside ``custom_fields`` \u2014 the payload\nmirrors DB structure rather than inventing top-level body keys for\nfields that don't have dedicated columns. ``additional_workorders``\nis a sibling top-level body property (the historical wire contract);\nthe backend persists it into ``custom_fields`` so a request awaiting\nreview still honors it at the deferred finalize.", "properties": {"project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "type": {"$ref": "#/components/schemas/ProjectScopeChangeRequestType", "description": "Type of scope change"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Change description", "title": "Description"}, "custom_fields": {"anyOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestCustomFields"}, {"type": "null"}], "description": "Scope-change metadata \u2014 service-replacement linkage and evidence file references. See ProjectScopeChangeRequestCustomFields."}, "additional_workorders": {"anyOf": [{"items": {"$ref": "#/components/schemas/ScopeChangeAdditionalWorkorder"}, "type": "array"}, {"type": "null"}], "description": "Optional follow-up generation step \u2014 service items from the replacement service to generate as NOT_STARTED workorders on the new SOL, each optionally narrowed to a subset of the source turbine's components. Strongly recommended; without this, the new SOL may end up at FIELD_COMPLETED right after the scope change because every migrated workorder is force-completed and no replacement-service work exists yet. Service item ids are validated at create time (must exist, be live, and belong to custom_fields.replacement_service_id \u2014 422 otherwise). Persisted into custom_fields so a request awaiting review still honors it when the finalize cascade eventually runs.", "title": "Additional Workorders"}, "initiated_from": {"allOf": [{"$ref": "#/components/schemas/ProjectScopeChangeRequestOrigin"}], "default": "OPSHUB", "description": "Origin client. AeroTask must send AEROTASK \u2014 evidence images are mandatory for AeroTask-initiated requests (422 without at least one custom_fields.evidence_file_ids entry). Defaults to OPSHUB, for which evidence stays optional."}}, "required": ["project_id", "type"], "title": "ProjectScopeChangeRequestCreate", "type": "object"}, "ProjectScopeChangeRequestCustomFields": {"additionalProperties": false, "description": "Structured custom_fields payload for a scope-change request.\n\nInherits ``extra = \"forbid\"`` from the base ``Schema`` \u2014 unknown keys\nare rejected with 422. Adding a new key is a deliberate schema change\nrather than an undocumented side channel; this keeps the OpenAPI\ncontract honest (no ``additionalProperties: true``) and catches typos\nin client payloads.", "properties": {"source_service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Source SOL id. Required when the scope change is a service replacement; must be paired with replacement_service_id.", "title": "Source Service Order Line Id"}, "source_turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "TurbineComponent (blade) id the change applies to. Only meaningful on a service replacement whose source SOL covers the whole turbine (no pinned component): only the chosen blade's workorders move to the new SOL, and the source SOL stays active for the other blades. Omit (or null) to change the whole turbine \u2014 the source SOL is cancelled as before. On a blade-pinned source SOL the field must be absent or equal the pinned component.", "title": "Source Turbine Component Id"}, "replacement_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Replacement service id. Required when the scope change is a service replacement; must be paired with source_service_order_line_id.", "title": "Replacement Service Id"}, "evidence_file_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "core.File ids of evidence files previously uploaded via POST /api/core/v1/files. The backend creates a FileEntityLink row per id in the same transaction as the SCR; unknown ids cause the whole create to roll back with 422. The ids also persist in this JSON column as the historical input contract.", "title": "Evidence File Ids"}, "additional_workorders": {"anyOf": [{"items": {"$ref": "#/components/schemas/ScopeChangeAdditionalWorkorder"}, "type": "array"}, {"type": "null"}], "description": "Persisted copy of the top-level create field of the same name. The backend writes it here so a request that awaits QC \u2192 Sales \u2192 PM review still knows which workorders to generate when the finalize cascade eventually runs (possibly days after creation). Read-only in practice \u2014 supply the top-level create field instead of writing this key directly.", "title": "Additional Workorders"}, "initial_evaluation_condition": {"anyOf": [{"$ref": "#/components/schemas/ScopeChangeInitialEvaluationCondition"}, {"type": "null"}], "description": "Blade condition per the initial (pre-sale) evaluation, filled by the QC / blade specialist."}, "current_condition": {"anyOf": [{"$ref": "#/components/schemas/ScopeChangeCurrentCondition"}, {"type": "null"}], "description": "Blade condition found in the field: measurements from the technician plus the QC / blade specialist's re-assessment."}}, "title": "ProjectScopeChangeRequestCustomFields", "type": "object"}, "ScopeChangeCurrentCondition": {"additionalProperties": false, "description": "Blade condition found in the field, motivating the scope change.", "properties": {"blade_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Serial number of the assessed blade.", "title": "Blade Serial Number"}, "damage_length_mm": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Damage length in millimetres.", "title": "Damage Length Mm"}, "damage_width_mm": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Damage width in millimetres.", "title": "Damage Width Mm"}, "distance_from_tip_from_m": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Start of the distance-from-tip range, metres.", "title": "Distance From Tip From M"}, "distance_from_tip_to_m": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "End of the distance-from-tip range, metres.", "title": "Distance From Tip To M"}, "distance_from_root_m": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Distance from the blade root, metres.", "title": "Distance From Root M"}, "service_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Assessed service code, e.g. 'LER-3' or 'RAT'.", "title": "Service Type"}, "damage_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage type label, e.g. 'Erosion' or 'Lightning damage'.", "title": "Damage Type"}, "category": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage category label, e.g. 'CAT3'.", "title": "Category"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade side, e.g. 'Leading Edge' or 'Suction Side'.", "title": "Side"}, "repair_duration_h": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Estimated repair duration in hours.", "title": "Repair Duration H"}, "repair_cost": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Repair cost in the project's currency, excluding mobilization costs.", "title": "Repair Cost"}, "image_file_ids": {"anyOf": [{"items": {"type": "integer"}, "maxItems": 3, "type": "array"}, {"type": "null"}], "description": "core.File ids of this section's photos (at most 3), pre-uploaded via POST /api/core/v1/files. Linked to the request as FileEntityLink rows alongside evidence_file_ids.", "title": "Image File Ids"}, "technician_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text note from the technician in the field.", "title": "Technician Comment"}, "blade_specialist_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text note from the QC / blade specialist.", "title": "Blade Specialist Comment"}}, "title": "ScopeChangeCurrentCondition", "type": "object"}, "ScopeChangeInitialEvaluationCondition": {"additionalProperties": false, "description": "Blade condition as assessed at the initial (pre-sale) evaluation.", "properties": {"blade_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Serial number of the assessed blade.", "title": "Blade Serial Number"}, "damage_length_mm": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Damage length in millimetres.", "title": "Damage Length Mm"}, "damage_width_mm": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Damage width in millimetres.", "title": "Damage Width Mm"}, "distance_from_tip_from_m": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Start of the distance-from-tip range, metres.", "title": "Distance From Tip From M"}, "distance_from_tip_to_m": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "End of the distance-from-tip range, metres.", "title": "Distance From Tip To M"}, "distance_from_root_m": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Distance from the blade root, metres.", "title": "Distance From Root M"}, "service_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Assessed service code, e.g. 'LER-3' or 'RAT'.", "title": "Service Type"}, "damage_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage type label, e.g. 'Erosion' or 'Lightning damage'.", "title": "Damage Type"}, "category": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Damage category label, e.g. 'CAT3'.", "title": "Category"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade side, e.g. 'Leading Edge' or 'Suction Side'.", "title": "Side"}, "repair_duration_h": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Estimated repair duration in hours.", "title": "Repair Duration H"}, "repair_cost": {"anyOf": [{"minimum": 0.0, "type": "number"}, {"type": "null"}], "description": "Repair cost in the project's currency, excluding mobilization costs.", "title": "Repair Cost"}, "image_file_ids": {"anyOf": [{"items": {"type": "integer"}, "maxItems": 3, "type": "array"}, {"type": "null"}], "description": "core.File ids of this section's photos (at most 3), pre-uploaded via POST /api/core/v1/files. Linked to the request as FileEntityLink rows alongside evidence_file_ids.", "title": "Image File Ids"}}, "title": "ScopeChangeInitialEvaluationCondition", "type": "object"}, "ProjectScopeChangeRequestUpdate": {"additionalProperties": false, "description": "Fields editable on a request that still awaits its first (QC) review.\n\nThe endpoint 422s on any other status \u2014 later review stages, APPROVED\n(the cascade ran) and REJECTED (terminal) are immutable; correcting\nthose means reject + recreate. The source SOL and type are deliberately\nnot editable: re-pointing the request at a different line is a new\nrequest. ``replacement_service_id`` and ``additional_workorders`` live\nin ``custom_fields`` on the row; they are top-level here so the\neditable surface stays an explicit whitelist.", "properties": {"description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Change description", "title": "Description"}, "replacement_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "New replacement service (stored as custom_fields.replacement_service_id). Must be an LER service. When it changes, additional_workorders must be re-submitted in the same call \u2014 the previously selected service items belong to the old replacement service.", "title": "Replacement Service Id"}, "additional_workorders": {"anyOf": [{"items": {"$ref": "#/components/schemas/ScopeChangeAdditionalWorkorder"}, "type": "array"}, {"type": "null"}], "description": "Replaces the persisted additional_workorders plan; validated against the (possibly new) replacement service. Pass an empty list to clear the plan.", "title": "Additional Workorders"}, "evidence_file_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Replaces the linked evidence set. Ids are diffed against the current set: newly added ids get a FileEntityLink row (pre-upload the binaries via POST /api/core/v1/files), removed ids get their link soft-deleted. The AeroTask minimum-evidence rule applies at create time only \u2014 the QC reviewer editing a request may remove all images.", "title": "Evidence File Ids"}, "initial_evaluation_condition": {"anyOf": [{"$ref": "#/components/schemas/ScopeChangeInitialEvaluationCondition"}, {"type": "null"}], "description": "Replaces the stored initial-evaluation condition section (custom_fields.initial_evaluation_condition). Pass null to clear it; omit to leave it unchanged. Its image_file_ids are diffed into FileEntityLink rows like evidence_file_ids."}, "current_condition": {"anyOf": [{"$ref": "#/components/schemas/ScopeChangeCurrentCondition"}, {"type": "null"}], "description": "Replaces the stored current-condition section (custom_fields.current_condition). Pass null to clear it; omit to leave it unchanged. Its image_file_ids are diffed into FileEntityLink rows like evidence_file_ids."}}, "title": "ProjectScopeChangeRequestUpdate", "type": "object"}, "ProjectScopeChangeRequestApproveBody": {"additionalProperties": false, "description": "Body for POST /project-scope-change-requests/{id}/approve.", "properties": {"expected_status": {"$ref": "#/components/schemas/ProjectScopeChangeRequestWaitingStatus", "description": "The status the caller believes the request is in \u2014 an optimistic-concurrency token. Each call advances the state machine exactly one stage; a mismatch (double-click, racing reviewer, terminal status) yields 422 with zero side effects. The caller needs the approval permission of this stage."}, "note": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional note recorded on the status change log entry.", "title": "Note"}}, "required": ["expected_status"], "title": "ProjectScopeChangeRequestApproveBody", "type": "object"}, "ProjectScopeChangeRequestWaitingStatus": {"description": "The three review stages an approve/reject action may target.", "enum": ["WAITING_FOR_QC", "WAITING_FOR_SALES", "WAITING_FOR_PM"], "title": "ProjectScopeChangeRequestWaitingStatus", "type": "string"}, "ProjectScopeChangeRequestRejectBody": {"additionalProperties": false, "description": "Body for POST /project-scope-change-requests/{id}/reject.", "properties": {"expected_status": {"$ref": "#/components/schemas/ProjectScopeChangeRequestWaitingStatus", "description": "The status the caller believes the request is in \u2014 same optimistic-concurrency semantics as /approve. Reject is gated by the same stage permission that gates approve."}, "reason": {"description": "Mandatory non-blank rejection reason \u2014 stamped on the request and recorded in the status change log.", "minLength": 1, "title": "Reason", "type": "string"}}, "required": ["expected_status", "reason"], "title": "ProjectScopeChangeRequestRejectBody", "type": "object"}, "ProjectQueryParams": {"additionalProperties": false, "description": "Query parameters for projects endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Case-insensitive match on project code or names of linked locations (active project\u2013location links only). SOL-number lookup lives in GET /core/v1/projects/search. Each project is returned at most once.", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "requesting_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by requesting customer ID (ignored when requesting_customer_ids is set)", "title": "Requesting Customer Id"}, "billing_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by billing customer ID (ignored when billing_customer_ids is set)", "title": "Billing Customer Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by vendor ID (ignored when vendor_ids is set)", "title": "Vendor Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID (ignored when country_ids is set)", "title": "Country Id"}, "status_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by status ID (ignored when status_ids is set)", "title": "Status Id"}, "project_manager_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project manager ID (ignored when project_manager_ids is set)", "title": "Project Manager Id"}, "salesperson_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by salesperson ID (ignored when salesperson_ids is set)", "title": "Salesperson Id"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project type (REGULAR, WARRANTY, DEMO, RND, ACADEMY, or INTERNAL)", "title": "Type"}, "types": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated project types (OR within), e.g. REGULAR,WARRANTY. Empty/omitted = no type filter. When set, type is ignored.", "title": "Types"}, "status_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated status IDs (OR within). Empty/omitted = no status filter. When set, status_id is ignored.", "title": "Status Ids"}, "country_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated country IDs (OR within). Empty/omitted = no country filter. When set, country_id is ignored.", "title": "Country Ids"}, "requesting_customer_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated requesting customer IDs (OR within). Empty/omitted = no filter on this facet. When set, requesting_customer_id is ignored.", "title": "Requesting Customer Ids"}, "billing_customer_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated billing customer IDs (OR within). Empty/omitted = no filter on this facet. When set, billing_customer_id is ignored.", "title": "Billing Customer Ids"}, "vendor_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated vendor IDs (OR within). Empty/omitted = no vendor filter. When set, vendor_id is ignored.", "title": "Vendor Ids"}, "project_manager_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated project manager user IDs (OR within). Empty/omitted = no filter on this facet. When set, project_manager_id is ignored.", "title": "Project Manager Ids"}, "salesperson_ids": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated salesperson user IDs (OR within). Empty/omitted = no filter on this facet. When set, salesperson_id is ignored.", "title": "Salesperson Ids"}, "scope": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "'mine' or 'all'", "title": "Scope"}}, "title": "ProjectQueryParams", "type": "object"}, "CountryWithRegionObject": {"additionalProperties": false, "description": "CountryObject extended with region \u2014 only for responses that prefetch country__region.", "properties": {"id": {"description": "Country ID", "title": "Id", "type": "integer"}, "code": {"description": "Country code (ISO 3166-1 alpha-2)", "title": "Code", "type": "string"}, "name": {"description": "Country name", "title": "Name", "type": "string"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Region name (nullable)", "title": "Region"}}, "required": ["id", "code", "name"], "title": "CountryWithRegionObject", "type": "object"}, "ProjectLocationSummary": {"additionalProperties": false, "description": "Summary of sites (locations) linked to a project for list/detail payloads.", "properties": {"primary_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name of the first linked site when ordered by project_location id ascending", "title": "Primary Name"}, "total_count": {"description": "Number of active project\u2013site links", "minimum": 0, "title": "Total Count", "type": "integer"}, "all_names": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "All site names when total_count > 1; omitted or null when absent or unnecessary", "title": "All Names"}}, "required": ["total_count"], "title": "ProjectLocationSummary", "type": "object"}, "ProjectResponse": {"additionalProperties": false, "description": "Schema for Project response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Project ID", "title": "Id", "type": "integer"}, "code": {"description": "Unique project code", "title": "Code", "type": "string"}, "type": {"description": "Project type: REGULAR, WARRANTY, DEMO, RND, ACADEMY, or INTERNAL", "title": "Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project description", "title": "Description"}, "is_offshore": {"default": false, "description": "Read-only, auto-derived: true iff any active project location points to a location with windpark_type='Offshore'. Kept in sync by core.signals; not writable through this API.", "title": "Is Offshore", "type": "boolean"}, "requesting_customer": {"anyOf": [{"$ref": "#/components/schemas/CustomerObject"}, {"type": "null"}], "description": "Requesting customer"}, "billing_customer": {"anyOf": [{"$ref": "#/components/schemas/CustomerObject"}, {"type": "null"}], "description": "Billing customer"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/VendorObject"}, {"type": "null"}], "description": "Vendor"}, "country": {"anyOf": [{"$ref": "#/components/schemas/CountryWithRegionObject"}, {"type": "null"}], "description": "Country"}, "timezone": {"anyOf": [{"$ref": "#/components/schemas/TimezoneObject"}, {"type": "null"}], "description": "Timezone"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ProjectStatusObject"}, {"type": "null"}], "description": "Project status"}, "project_manager": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "Project manager"}, "salesperson": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "Salesperson"}, "pipedrive_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pipedrive deal ID", "title": "Pipedrive Id"}, "pipedrive_probability": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Latest deal probability (0-100). Mirrored from Pipedrive during the deals-refresh poll unless probability_manually_overridden is true, in which case it holds the value set by a manual RFI edit.", "title": "Pipedrive Probability"}, "probability_manually_overridden": {"default": false, "description": "True when pipedrive_probability was set by a manual RFI edit and is therefore sticky against the Pipedrive deals-refresh poll. Cleared when the probability is set to null via the RFI form.", "title": "Probability Manually Overridden", "type": "boolean"}, "pre_job_received_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Timestamp when the customer pre-job questionnaire was received (set on submit via PUT /projects/{id}/pre-job-received). Non-null means the questionnaire is submitted/locked; null means it is still editable.", "title": "Pre Job Received At"}, "project_builder_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Project builder project UUID (legacy)", "title": "Project Builder Id"}, "planned_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Planned project start date", "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Planned project end date", "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Actual project start date", "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Actual project end date", "title": "Actual End Date"}, "expected_close_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "When sales expects the deal to be decided. Owned by the sales form: it writes this on deal creation and again whenever the date moves on its pipeline board, so a later change there wins over a hand-edit made in Ops Hub. Commercial only: no cascade or schedule reads it.", "title": "Expected Close Date"}, "potential_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Potential project start date: the soonest start_date across the project's planned resource sets (MIN over ProjectPlannedResourceSet items). Distinct from planned_start_date (Wrike). Null when the project has no planned set with a start date.", "title": "Potential Start Date"}, "potential_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Potential project end date: the latest end_date across the project's planned resource sets (MAX over ProjectPlannedResourceSet items). Distinct from planned_end_date (Wrike). Null when the project has no planned set with an end date.", "title": "Potential End Date"}, "lps_standard": {"anyOf": [{"$ref": "#/components/schemas/StandardObject"}, {"type": "null"}], "description": "Selected LPS report template/standard (passed to the reporting engine as lps_standard_id). Null when not yet picked or for non-LPS projects."}, "scope_change_auto_accept_enabled": {"default": false, "description": "When true, scope change requests on this project are auto-approved and finalized immediately on creation (legacy behaviour). When false, requests enter the QC \u2192 Sales \u2192 PM approval flow.", "title": "Scope Change Auto Accept Enabled", "type": "boolean"}, "location_summary": {"$ref": "#/components/schemas/ProjectLocationSummary", "description": "Linked sites summary; primary follows ascending project_location id"}, "billing_currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency code from the project's billing record (e.g. EUR, USD).", "title": "Billing Currency"}, "warranty_counterpart_project": {"anyOf": [{"$ref": "#/components/schemas/WarrantyCounterpartProjectObject"}, {"type": "null"}], "description": "The project on the other side of the warranty relationship: the source project (on a WARRANTY project) or the warranty project (on a REGULAR project). Null when there is no linkage."}}, "required": ["updated_at", "id", "code", "type", "location_summary"], "title": "ProjectResponse", "type": "object"}, "ProjectStatusObject": {"additionalProperties": false, "description": "Nested project status object for responses (no timestamps).", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "ProjectStatusObject", "type": "object"}, "StandardObject": {"additionalProperties": false, "description": "Nested ``core.standard`` object for responses (LPS / HVT templates).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"title": "Type", "type": "string"}, "key": {"title": "Key", "type": "string"}}, "required": ["id", "name", "type", "key"], "title": "StandardObject", "type": "object"}, "WarrantyCounterpartProjectObject": {"additionalProperties": false, "description": "The project on the other side of a warranty relationship (no timestamps).\n\nDirection-neutral: the source project (on a WARRANTY project) or the warranty\nproject (on a REGULAR project). ``type`` lets the client tell which without\ninferring from the current project's type.", "properties": {"id": {"description": "Counterpart project ID", "title": "Id", "type": "integer"}, "code": {"description": "Counterpart project code", "title": "Code", "type": "string"}, "type": {"description": "Counterpart project type", "title": "Type", "type": "string"}, "project_builder_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Counterpart project builder UUID (for frontend routing)", "title": "Project Builder Id"}}, "required": ["id", "code", "type"], "title": "WarrantyCounterpartProjectObject", "type": "object"}, "ProjectCreate": {"additionalProperties": false, "description": "Schema for creating a Project.", "properties": {"code": {"description": "Unique project code", "minLength": 1, "title": "Code", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project type: REGULAR, DEMO, RND, or ACADEMY. Defaults to REGULAR when omitted. WARRANTY and INTERNAL cannot be set via the API.", "title": "Type"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project description", "title": "Description"}, "requesting_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Requesting customer ID", "title": "Requesting Customer Id"}, "billing_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Billing customer ID", "title": "Billing Customer Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Vendor ID", "title": "Vendor Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID", "title": "Timezone Id"}, "status_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project status ID", "title": "Status Id"}, "project_manager_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project manager user ID", "title": "Project Manager Id"}, "salesperson_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Salesperson user ID", "title": "Salesperson Id"}, "pipedrive_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pipedrive deal ID", "title": "Pipedrive Id"}, "pipedrive_probability": {"anyOf": [{"maximum": 100, "minimum": 0, "type": "integer"}, {"type": "null"}], "description": "Deal probability (0-100). Sending it here is a manual override, exactly as it is on PATCH: the value is marked sticky so the Pipedrive deals-refresh poll no longer overwrites it. Unlike PATCH this does not re-run the status cascade, because a project that has just been created has no internally-approved commercial offer and so cannot advance past Upcoming whatever the probability says. Omit it to leave Pipedrive in control.", "title": "Pipedrive Probability"}, "project_builder_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Project builder project UUID (legacy) - optional for natively created projects", "title": "Project Builder Id"}, "planned_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Planned project start date", "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Planned project end date", "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Actual project start date", "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Actual project end date", "title": "Actual End Date"}, "expected_close_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "When sales expects the deal to be decided. Owned by the sales form: it writes this on deal creation and again whenever the date moves on its pipeline board, so a later change there wins over a hand-edit made in Ops Hub. Commercial only: no cascade or schedule reads it.", "title": "Expected Close Date"}, "lps_standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of the LPS report template/standard (core.standard)", "title": "Lps Standard Id"}}, "required": ["code"], "title": "ProjectCreate", "type": "object"}, "ProjectSearchResult": {"additionalProperties": false, "description": "One global-search hit: a project row or a service-order-line (SOL) row.\n\nProject rows match on project code or an active linked location name;\nSOL rows match on the SOL number. Both row kinds point at a project, so\n``project_id`` / ``project_builder_id`` always identify the navigation\ntarget.", "properties": {"type": {"description": "Kind of hit: a project itself or one of its SOLs", "enum": ["project", "sol"], "title": "Type", "type": "string"}, "project_id": {"description": "Numeric Core project ID", "title": "Project Id", "type": "integer"}, "project_code": {"description": "Project code", "title": "Project Code", "type": "string"}, "project_builder_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Project builder project UUID (legacy)", "title": "Project Builder Id"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Requesting customer name of the project", "title": "Customer Name"}, "matched_location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the linked site the term matched; set on project rows only, and only when a site (not just the code) matched", "title": "Matched Location Name"}, "sol_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ServiceOrderLine ID; set on sol rows only", "title": "Sol Id"}, "sol_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "SOL number; set on sol rows only", "title": "Sol Number"}}, "required": ["type", "project_id", "project_code"], "title": "ProjectSearchResult", "type": "object"}, "ProjectUpdate": {"additionalProperties": false, "description": "Schema for updating a Project.", "properties": {"code": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "description": "Unique project code", "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project description", "title": "Description"}, "requesting_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Requesting customer ID", "title": "Requesting Customer Id"}, "billing_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Billing customer ID", "title": "Billing Customer Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Vendor ID", "title": "Vendor Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Country ID", "title": "Country Id"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Timezone ID", "title": "Timezone Id"}, "status_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project status ID", "title": "Status Id"}, "project_manager_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project manager user ID", "title": "Project Manager Id"}, "salesperson_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Salesperson user ID", "title": "Salesperson Id"}, "pipedrive_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pipedrive deal ID", "title": "Pipedrive Id"}, "pipedrive_probability": {"anyOf": [{"maximum": 100, "minimum": 0, "type": "integer"}, {"type": "null"}], "description": "Deal probability (0-100). Editing it here is a manual RFI override: it drives the master-planning status cascade (Upcoming->Initiation at >=90, Initiation->Planning at 100), re-runs the status recompute, and marks the value sticky so the Pipedrive deals-refresh poll no longer overwrites it. Setting it to null clears the override and hands control back to Pipedrive.", "title": "Pipedrive Probability"}, "project_builder_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Project builder project UUID (legacy)", "title": "Project Builder Id"}, "planned_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Planned project start date", "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Planned project end date", "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Actual project start date", "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Actual project end date", "title": "Actual End Date"}, "expected_close_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "When sales expects the deal to be decided. Owned by the sales form: it writes this on deal creation and again whenever the date moves on its pipeline board, so a later change there wins over a hand-edit made in Ops Hub. Commercial only: no cascade or schedule reads it.", "title": "Expected Close Date"}, "lps_standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of the LPS report template/standard (core.standard)", "title": "Lps Standard Id"}, "pre_job_received_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Customer pre-job questionnaire 'received' timestamp. Non-null locks the questionnaire; null reopens it. Writing it through this generic update is a plain persist with no side effects \u2014 prefer the PUT /projects/{id}/pre-job-received action endpoint, which also sends the submission email and re-runs the status cascade on submit.", "title": "Pre Job Received At"}, "scope_change_auto_accept_enabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "When true, scope change requests on this project are auto-approved and finalized immediately on creation; when false they enter the QC \u2192 Sales \u2192 PM review flow. Field-level permission: including this field in the body requires auth.project_manager \u2014 403 otherwise.", "title": "Scope Change Auto Accept Enabled"}}, "title": "ProjectUpdate", "type": "object"}, "ProjectOverviewReportRecipient": {"additionalProperties": false, "description": "Report recipient (customer contact) shown on the project overview.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Contact name", "title": "Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Contact email", "title": "Email"}}, "title": "ProjectOverviewReportRecipient", "type": "object"}, "ProjectOverviewResponse": {"additionalProperties": false, "description": "Decoupled project overview payload (Core/dispatch-sourced).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "project_folder_link": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Google Drive ROOT folder URL (core.ProjectGoogleDriveLink)", "title": "Project Folder Link"}, "report_recipients": {"description": "Report recipients (core.ProjectContact)", "items": {"$ref": "#/components/schemas/ProjectOverviewReportRecipient"}, "title": "Report Recipients", "type": "array"}, "dedicated_contact_for_scope_change": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Pre-job answer (core.ProjectPreJobAnswers)", "title": "Dedicated Contact For Scope Change"}, "is_lps_project": {"default": false, "description": "Whether the scope includes any LPS service", "title": "Is Lps Project", "type": "boolean"}, "robotic_sets": {"description": "Planned resource set names", "items": {"$ref": "#/components/schemas/ProjectOverviewRoboticSet"}, "title": "Robotic Sets", "type": "array"}, "categories": {"description": "Service categories present in scope", "items": {"type": "string"}, "title": "Categories", "type": "array"}, "service_full_codes": {"description": "Service codes present in scope", "items": {"type": "string"}, "title": "Service Full Codes", "type": "array"}, "blades": {"default": 0, "description": "Distinct blade-level scope items", "title": "Blades", "type": "integer"}, "turbines": {"default": 0, "description": "Distinct turbines in scope", "title": "Turbines", "type": "integer"}, "total_units": {"default": 0, "description": "blades + turbines", "title": "Total Units", "type": "integer"}, "rat_needed": {"default": false, "description": "Whether any service code requires RAT", "title": "Rat Needed", "type": "boolean"}, "sites": {"description": "Project sites", "items": {"$ref": "#/components/schemas/ProjectOverviewSite"}, "title": "Sites", "type": "array"}, "reinspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Reinspection flag (legacy projects.PipedriveDeal)", "title": "Reinspection"}, "rope_access_contract": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Rope access contract link (legacy projects.ProjectOverviewInfo)", "title": "Rope Access Contract"}, "project_status_dashboard": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project status dashboard link (legacy projects.ProjectOverviewInfo)", "title": "Project Status Dashboard"}, "planned_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "MIN(planned resource set item start_date)", "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "MAX(planned resource set item end_date)", "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Earliest non-cancelled workorder activity start", "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Latest completed workorder activity end", "title": "Actual End Date"}, "planned_duration": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Human-readable planned duration", "title": "Planned Duration"}}, "required": ["updated_at"], "title": "ProjectOverviewResponse", "type": "object"}, "ProjectOverviewRoboticSet": {"additionalProperties": false, "description": "Planned resource set name shown on the project overview.", "properties": {"name": {"description": "Planned resource set name", "title": "Name", "type": "string"}}, "required": ["name"], "title": "ProjectOverviewRoboticSet", "type": "object"}, "ProjectOverviewSite": {"additionalProperties": false, "description": "A project site with coordinates for the overview list.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Location name", "title": "Name"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude", "title": "Longitude"}}, "title": "ProjectOverviewSite", "type": "object"}, "ProjectOverviewEdit": {"additionalProperties": false, "description": "Editable project overview fields. Writes span Core + legacy tables.\n\nOnly explicitly-sent keys are applied (``exclude_unset=True``).", "properties": {"project_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Writes core.Project.description", "title": "Project Description"}, "lps_standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Writes core.Project.lps_standard_id", "title": "Lps Standard Id"}, "rope_access_contract": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Writes legacy projects.ProjectOverviewInfo", "title": "Rope Access Contract"}, "project_status_dashboard": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Writes legacy projects.ProjectOverviewInfo", "title": "Project Status Dashboard"}, "gross_margin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Writes legacy projects.ProjectOverviewInfo", "title": "Gross Margin"}, "reinspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Writes legacy projects.PipedriveDeal (+ BusinessTravelOrder mirror)", "title": "Reinspection"}}, "title": "ProjectOverviewEdit", "type": "object"}, "ProjectOverviewFinancialsResponse": {"additionalProperties": false, "description": "Decoupled project financial overview (Core + accounting).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "co_value": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approved offer total (Sum of items.amount)", "title": "Co Value"}, "charged_value": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Charged value (NetSuite service charges)", "title": "Charged Value"}, "purchase_order_value": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of purchase order version amounts", "title": "Purchase Order Value"}, "actual_units_done": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Distinct charged top-level scope items", "title": "Actual Units Done"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing currency code", "title": "Currency"}, "offer_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status of the latest project offer", "title": "Offer Status"}, "gross_margin": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Gross margin note (legacy projects.ProjectOverviewInfo)", "title": "Gross Margin"}}, "required": ["updated_at"], "title": "ProjectOverviewFinancialsResponse", "type": "object"}, "ProjectStatusHistoryEntry": {"additionalProperties": false, "description": "A single project status transition (for the overview status timeline).", "properties": {"old_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status the project moved from (null for the first entry)", "title": "Old Status"}, "new_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status the project moved to", "title": "New Status"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Trigger that caused the change (e.g. create, pipedrive, sol_cascade, completion_check, manual, reconcile).", "title": "Change Reason"}, "change_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional free-text note about the change", "title": "Change Note"}, "status_changed_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "When the transition occurred (ISO 8601)", "title": "Status Changed At"}, "changed_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name or email of the user who caused the change, if known", "title": "Changed By"}}, "title": "ProjectStatusHistoryEntry", "type": "object"}, "ProjectValidateResponse": {"additionalProperties": false, "description": "Response schema for project validation endpoint.", "properties": {"warnings": {"items": {"type": "string"}, "title": "Warnings", "type": "array"}}, "required": ["warnings"], "title": "ProjectValidateResponse", "type": "object"}, "ProjectStatusOverride": {"additionalProperties": false, "description": "Payload for the manual status-override action endpoint.", "properties": {"status_code": {"description": "Target ProjectStatus code (e.g. 'Planning'). Matched case-insensitively against the configured statuses; 'Cancelled' is refused \u2014 cancellation has its own flow.", "title": "Status Code", "type": "string"}, "reason": {"description": "Why the status is overridden. Required non-blank; stored on the status change log and shown in the status history.", "maxLength": 1000, "title": "Reason", "type": "string"}}, "required": ["status_code", "reason"], "title": "ProjectStatusOverride", "type": "object"}, "ProjectPreJobReceivedUpdate": {"additionalProperties": false, "description": "Payload for the pre-job-received action endpoint.\n\nOnly the *null-ness* of ``pre_job_received_at`` is read: a non-null value\nmarks the questionnaire as submitted (and locks it), ``null`` reopens it.\nOn submit the timestamp is stamped server-side, so any non-null value sent\nhere is treated purely as the \"submitted\" signal \u2014 its value is ignored.", "properties": {"pre_job_received_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Submit/reopen signal. Non-null = submitted (locks the pre-job questionnaire; the stored timestamp is stamped server-side); null = reopened (unlocks it).", "title": "Pre Job Received At"}}, "required": ["pre_job_received_at"], "title": "ProjectPreJobReceivedUpdate", "type": "object"}, "PurchaseOrderQueryParams": {"additionalProperties": false, "description": "Query params for PurchaseOrder list.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Case-insensitive search across version order numbers", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field (prefix with - for descending)", "title": "Sort"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}}, "title": "PurchaseOrderQueryParams", "type": "object"}, "PurchaseOrderCreate": {"additionalProperties": false, "description": "Create a PurchaseOrder with its initial (v1) version. File is optional.", "properties": {"customer_id": {"description": "Customer that issued the PO", "title": "Customer Id", "type": "integer"}, "currency_id": {"description": "Currency for all versions of this PO", "title": "Currency Id", "type": "integer"}, "order_number": {"description": "Order number shown on the initial document", "minLength": 1, "title": "Order Number", "type": "string"}, "issue_date": {"description": "Issue date shown on the initial document", "format": "date", "title": "Issue Date", "type": "string"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "description": "Amount on the initial document", "title": "Amount"}, "file_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Optional File id to attach to the initial version", "title": "File Id"}, "project_ids": {"description": "Projects this PO covers (optional, can be set later)", "items": {"type": "integer"}, "title": "Project Ids", "type": "array"}}, "required": ["customer_id", "currency_id", "order_number", "issue_date", "amount"], "title": "PurchaseOrderCreate", "type": "object"}, "PurchaseOrderUpdate": {"additionalProperties": false, "description": "Partial update of the PurchaseOrder-level fields.\n\nVersion-scoped fields (order_number, issue_date, amount) are immutable\nhere \u2014 correct them by adding a new version via the dedicated endpoint.", "properties": {"customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer that issued the PO", "title": "Customer Id"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Currency for the PO", "title": "Currency Id"}}, "title": "PurchaseOrderUpdate", "type": "object"}, "PurchaseOrderVersionQueryParams": {"additionalProperties": false, "description": "Query params for version list under a PO.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by order_number", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field (prefix with - for descending)", "title": "Sort"}}, "title": "PurchaseOrderVersionQueryParams", "type": "object"}, "PurchaseOrderVersionResponse": {"additionalProperties": false, "description": "PurchaseOrderVersion response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "purchase_order_id": {"title": "Purchase Order Id", "type": "integer"}, "version_number": {"title": "Version Number", "type": "integer"}, "order_number": {"title": "Order Number", "type": "string"}, "issue_date": {"format": "date", "title": "Issue Date", "type": "string"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "file_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "File Id"}}, "required": ["updated_at", "id", "purchase_order_id", "version_number", "order_number", "issue_date", "amount"], "title": "PurchaseOrderVersionResponse", "type": "object"}, "PurchaseOrderVersionCreate": {"additionalProperties": false, "description": "Add a new version (amendment) to an existing PO. File is optional.", "properties": {"order_number": {"minLength": 1, "title": "Order Number", "type": "string"}, "issue_date": {"format": "date", "title": "Issue Date", "type": "string"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "file_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Optional File id to attach to this version", "title": "File Id"}}, "required": ["order_number", "issue_date", "amount"], "title": "PurchaseOrderVersionCreate", "type": "object"}, "PurchaseOrderVersionUpdate": {"additionalProperties": false, "description": "Partial update of a version's scalar fields.\n\nDoes not change `version_number` or swap the attached file. To replace\nthe file, use POST /purchase-order-versions/{id}/file.", "properties": {"order_number": {"anyOf": [{"minLength": 1, "type": "string"}, {"type": "null"}], "title": "Order Number"}, "issue_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Issue Date"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Amount"}}, "title": "PurchaseOrderVersionUpdate", "type": "object"}, "PurchaseOrderVersionFileReplaceRequest": {"additionalProperties": false, "description": "Replace the active file linked to a version.", "properties": {"file_id": {"title": "File Id", "type": "integer"}}, "required": ["file_id"], "title": "PurchaseOrderVersionFileReplaceRequest", "type": "object"}, "PurchaseOrderProjectQueryParams": {"additionalProperties": false, "description": "Query params for project link list under a PO.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}}, "title": "PurchaseOrderProjectQueryParams", "type": "object"}, "PurchaseOrderProjectResponse": {"additionalProperties": false, "description": "PurchaseOrderProject link response.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "purchase_order_id": {"title": "Purchase Order Id", "type": "integer"}, "project_id": {"title": "Project Id", "type": "integer"}, "allocated_amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Allocated Amount"}, "charges_total": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Sum of all active charges for this project (usage against this PO).", "title": "Charges Total"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project code for display.", "title": "Project Code"}, "project_builder_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "UUID used in project URLs.", "title": "Project Builder Id"}}, "required": ["updated_at", "id", "purchase_order_id", "project_id"], "title": "PurchaseOrderProjectResponse", "type": "object"}, "PurchaseOrderProjectCreate": {"additionalProperties": false, "description": "Link a project to a PO.", "properties": {"project_id": {"title": "Project Id", "type": "integer"}, "allocated_amount": {"anyOf": [{"exclusiveMinimum": 0.0, "type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Optional budget allocation for this project. When set, budget warnings use this value instead of the full PO amount.", "title": "Allocated Amount"}}, "required": ["project_id"], "title": "PurchaseOrderProjectCreate", "type": "object"}, "PurchaseOrderProjectUpdate": {"additionalProperties": false, "description": "Update the allocation for an existing PO-project link.", "properties": {"allocated_amount": {"anyOf": [{"exclusiveMinimum": 0.0, "type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Set to a value to cap this project's PO budget, or null to use the full PO amount.", "title": "Allocated Amount"}}, "title": "PurchaseOrderProjectUpdate", "type": "object"}, "VehicleFleetSummary": {"additionalProperties": false, "description": "Summary counts for the fleet vehicles dashboard.", "properties": {"total": {"description": "Total non-archived vehicles", "title": "Total", "type": "integer"}, "in_project": {"description": "Vehicles with an accepted assignment", "title": "In Project", "type": "integer"}, "planned": {"description": "Vehicles with a planned (not yet accepted) assignment", "title": "Planned", "type": "integer"}, "available": {"description": "Vehicles available for assignment", "title": "Available", "type": "integer"}, "vor": {"description": "Vehicles off road (expired inspection or no active insurance)", "title": "Vor", "type": "integer"}}, "required": ["total", "in_project", "planned", "available", "vor"], "title": "VehicleFleetSummary", "type": "object"}, "VehicleQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by license plate, make, or model", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by vehicle type", "title": "Type"}, "vehicle_source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by vehicle source", "title": "Vehicle Source"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by office location", "title": "Location Id"}, "include_archived": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Include archived vehicles", "title": "Include Archived"}}, "title": "VehicleQueryParams", "type": "object"}, "NavirecLiveState": {"additionalProperties": false, "description": "Live tracking snapshot for a vehicle, joined from Navirec by plate.", "properties": {"status": {"description": "Derived status: ACTIVE (ignition on), PARKED (ignition off but reported \u226410min ago), OFFLINE (no recent report).", "title": "Status", "type": "string"}, "is_active": {"description": "Convenience flag \u2014 true when status is ACTIVE or PARKED.", "title": "Is Active", "type": "boolean"}, "ignition": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Ignition"}, "speed_kmh": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Speed Kmh"}, "last_seen": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Last Seen"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Longitude"}, "vehicle_uuid": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Uuid"}}, "required": ["status", "is_active"], "title": "NavirecLiveState", "type": "object"}, "VehicleInsuranceResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "type": {"title": "Type", "type": "string"}, "date_from": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date From"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "insurance_number": {"title": "Insurance Number", "type": "string"}}, "required": ["id", "type", "insurance_number"], "title": "VehicleInsuranceResponse", "type": "object"}, "VehicleResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "license_plate": {"title": "License Plate", "type": "string"}, "make": {"title": "Make", "type": "string"}, "model": {"title": "Model", "type": "string"}, "type": {"title": "Type", "type": "string"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "location_id": {"title": "Location Id", "type": "integer"}, "vehicle_source": {"title": "Vehicle Source", "type": "string"}, "telematics_provider": {"title": "Telematics Provider", "type": "string"}, "telematics_device_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Telematics Device Id"}, "rental_company": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rental Company"}, "rental_agreement_no": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rental Agreement No"}, "inspection_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Inspection To"}, "active_insurances": {"items": {"$ref": "#/components/schemas/VehicleInsuranceResponse"}, "title": "Active Insurances", "type": "array"}, "insurance_count": {"default": 0, "title": "Insurance Count", "type": "integer"}, "is_archived": {"default": false, "title": "Is Archived", "type": "boolean"}, "updated_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Updated At"}, "navirec": {"anyOf": [{"$ref": "#/components/schemas/NavirecLiveState"}, {"type": "null"}]}}, "required": ["id", "license_plate", "make", "model", "type", "location_id", "vehicle_source", "telematics_provider"], "title": "VehicleResponse", "type": "object"}, "VehicleCreate": {"additionalProperties": false, "properties": {"license_plate": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "License Plate"}, "make": {"title": "Make", "type": "string"}, "model": {"title": "Model", "type": "string"}, "type": {"title": "Type", "type": "string"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "location_id": {"title": "Location Id", "type": "integer"}, "vehicle_source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Source"}, "telematics_provider": {"anyOf": [{"enum": ["NAVIREC", "MOTIVE"], "type": "string"}, {"type": "null"}], "title": "Telematics Provider"}, "telematics_device_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Telematics Device Id"}, "rental_company": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rental Company"}, "rental_agreement_no": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rental Agreement No"}, "inspection_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Inspection To"}}, "required": ["make", "model", "type", "location_id"], "title": "VehicleCreate", "type": "object"}, "VehicleUpdate": {"additionalProperties": false, "properties": {"license_plate": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "License Plate"}, "make": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Make"}, "model": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Model"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "vehicle_source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Source"}, "telematics_provider": {"anyOf": [{"enum": ["NAVIREC", "MOTIVE"], "type": "string"}, {"type": "null"}], "title": "Telematics Provider"}, "telematics_device_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Telematics Device Id"}, "rental_company": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rental Company"}, "rental_agreement_no": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rental Agreement No"}, "inspection_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Inspection To"}}, "title": "VehicleUpdate", "type": "object"}, "VehicleInsuranceCreate": {"additionalProperties": false, "properties": {"type": {"title": "Type", "type": "string"}, "date_from": {"title": "Date From", "type": "string"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "insurance_number": {"title": "Insurance Number", "type": "string"}}, "required": ["type", "date_from", "insurance_number"], "title": "VehicleInsuranceCreate", "type": "object"}, "VehicleInsuranceUpdate": {"additionalProperties": false, "properties": {"type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "date_from": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date From"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "insurance_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Insurance Number"}}, "title": "VehicleInsuranceUpdate", "type": "object"}, "VehicleFleetAssignmentDiscrepancies": {"additionalProperties": false, "properties": {"items": {"items": {"$ref": "#/components/schemas/VehicleFleetAssignmentDiscrepancy"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "VehicleFleetAssignmentDiscrepancies", "type": "object"}, "VehicleFleetAssignmentDiscrepancy": {"additionalProperties": false, "properties": {"assignment_id": {"title": "Assignment Id", "type": "integer"}, "reasons": {"items": {"type": "string"}, "title": "Reasons", "type": "array"}}, "required": ["assignment_id", "reasons"], "title": "VehicleFleetAssignmentDiscrepancy", "type": "object"}, "VehicleFleetAssignmentQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by vehicle license plate or assignee name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by vehicle ID", "title": "Vehicle Id"}, "assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by assignee user ID", "title": "Assignee User Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}}, "title": "VehicleFleetAssignmentQueryParams", "type": "object"}, "FocalxInspectionResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "focalx_inspection_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Focalx Inspection Id"}, "status": {"title": "Status", "type": "string"}, "result_data": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Result Data"}, "error_message": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error Message"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Completed At"}}, "required": ["id", "status", "created_at"], "title": "FocalxInspectionResponse", "type": "object"}, "VehicleFleetAssignmentReportResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "type": {"title": "Type", "type": "string"}, "odometer": {"title": "Odometer", "type": "integer"}, "possession": {"title": "Possession", "type": "object"}, "safety": {"title": "Safety", "type": "object"}, "photos": {"items": {}, "title": "Photos", "type": "array"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "reported_date": {"title": "Reported Date", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "focalx_inspection": {"anyOf": [{"$ref": "#/components/schemas/FocalxInspectionResponse"}, {"type": "null"}]}}, "required": ["id", "type", "odometer", "possession", "safety", "photos", "reported_date", "created_at"], "title": "VehicleFleetAssignmentReportResponse", "type": "object"}, "VehicleFleetAssignmentResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "vehicle": {"$ref": "#/components/schemas/VehicleResponse"}, "assignee_user": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}]}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectObject"}, {"type": "null"}]}, "robot_set": {"anyOf": [{"$ref": "#/components/schemas/RobotSetObject"}, {"type": "null"}]}, "parent_assignment_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Parent Assignment Id"}, "status": {"title": "Status", "type": "string"}, "from_date": {"title": "From Date", "type": "string"}, "to_date": {"title": "To Date", "type": "string"}, "accept_report": {"anyOf": [{"$ref": "#/components/schemas/VehicleFleetAssignmentReportResponse"}, {"type": "null"}]}, "return_report": {"anyOf": [{"$ref": "#/components/schemas/VehicleFleetAssignmentReportResponse"}, {"type": "null"}]}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "current_odometer_at_accept": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Current Odometer At Accept"}, "current_odometer_at_return": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Current Odometer At Return"}, "accepted_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Accepted At"}, "returned_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Returned At"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "navirec": {"anyOf": [{"$ref": "#/components/schemas/NavirecLiveState"}, {"type": "null"}]}}, "required": ["id", "vehicle", "status", "from_date", "to_date", "created_at", "updated_at"], "title": "VehicleFleetAssignmentResponse", "type": "object"}, "VehicleFleetPlanSchema": {"additionalProperties": false, "properties": {"vehicle_id": {"title": "Vehicle Id", "type": "integer"}, "assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee User Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Date"}, "to_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "allow_unrostered": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "default": false, "title": "Allow Unrostered"}}, "required": ["vehicle_id", "from_date", "to_date"], "title": "VehicleFleetPlanSchema", "type": "object"}, "VehicleFleetAcceptSchema": {"additionalProperties": false, "properties": {"vehicle_id": {"title": "Vehicle Id", "type": "integer"}, "assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee User Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Date"}, "to_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Date"}, "odometer": {"maximum": 2147483647, "minimum": 0, "title": "Odometer", "type": "integer"}, "possession": {"title": "Possession", "type": "object"}, "safety": {"title": "Safety", "type": "object"}, "photos": {"default": [], "items": {}, "title": "Photos", "type": "array"}, "reported_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reported Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["vehicle_id", "from_date", "to_date", "odometer", "possession", "safety"], "title": "VehicleFleetAcceptSchema", "type": "object"}, "UserProjectsQueryParams": {"additionalProperties": false, "properties": {"user_id": {"title": "User Id", "type": "integer"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Date"}, "to_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Date"}}, "required": ["user_id", "from_date", "to_date"], "title": "UserProjectsQueryParams", "type": "object"}, "UserProjectOverlap": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}}, "required": ["id", "code"], "title": "UserProjectOverlap", "type": "object"}, "PlannerStatusResponse": {"additionalProperties": false, "properties": {"items": {"items": {"$ref": "#/components/schemas/PlannerStatusResult"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "PlannerStatusResponse", "type": "object"}, "PlannerStatusResult": {"additionalProperties": false, "properties": {"key": {"title": "Key", "type": "string"}, "status": {"title": "Status", "type": "string"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "available_codes": {"items": {"type": "string"}, "title": "Available Codes", "type": "array"}}, "required": ["key", "status"], "title": "PlannerStatusResult", "type": "object"}, "PlannerStatusItemInput": {"additionalProperties": false, "properties": {"key": {"title": "Key", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Date"}, "to_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Date"}}, "required": ["key"], "title": "PlannerStatusItemInput", "type": "object"}, "PlannerStatusRequest": {"additionalProperties": false, "properties": {"items": {"items": {"$ref": "#/components/schemas/PlannerStatusItemInput"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "PlannerStatusRequest", "type": "object"}, "VehicleFleetAcceptPlannedSchema": {"additionalProperties": false, "properties": {"odometer": {"maximum": 2147483647, "minimum": 0, "title": "Odometer", "type": "integer"}, "possession": {"title": "Possession", "type": "object"}, "safety": {"title": "Safety", "type": "object"}, "photos": {"default": [], "items": {}, "title": "Photos", "type": "array"}, "reported_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reported Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["odometer", "possession", "safety"], "title": "VehicleFleetAcceptPlannedSchema", "type": "object"}, "VehicleFleetUpdateSchema": {"additionalProperties": false, "properties": {"assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee User Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "from_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Date"}, "to_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "title": "VehicleFleetUpdateSchema", "type": "object"}, "VehicleFleetReturnSchema": {"additionalProperties": false, "properties": {"odometer": {"maximum": 2147483647, "minimum": 0, "title": "Odometer", "type": "integer"}, "possession": {"title": "Possession", "type": "object"}, "safety": {"title": "Safety", "type": "object"}, "photos": {"default": [], "items": {}, "title": "Photos", "type": "array"}, "reported_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reported Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["odometer", "possession", "safety"], "title": "VehicleFleetReturnSchema", "type": "object"}, "VehicleFleetInvoiceQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by invoice number", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by vehicle ID", "title": "Vehicle Id"}, "assignment_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by assignment ID", "title": "Assignment Id"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by invoice type", "title": "Type"}, "date_from": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter invoices from this date (inclusive)", "title": "Date From"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter invoices up to this date (inclusive)", "title": "Date To"}}, "title": "VehicleFleetInvoiceQueryParams", "type": "object"}, "VehicleFleetInvoiceLineResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vehicle Id"}, "vehicle_license_plate": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle License Plate"}, "vehicle_label": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Label"}, "assignment_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignment Id"}, "type": {"title": "Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "currency": {"title": "Currency", "type": "string"}}, "required": ["id", "type", "amount", "currency"], "title": "VehicleFleetInvoiceLineResponse", "type": "object"}, "VehicleFleetInvoiceResponse": {"additionalProperties": false, "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"title": "Id", "type": "integer"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "vendor": {"title": "Vendor", "type": "string"}, "invoice_number": {"title": "Invoice Number", "type": "string"}, "lines": {"default": [], "items": {"$ref": "#/components/schemas/VehicleFleetInvoiceLineResponse"}, "title": "Lines", "type": "array"}, "total_amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "default": "0", "title": "Total Amount"}}, "required": ["updated_at", "id", "date", "vendor", "invoice_number"], "title": "VehicleFleetInvoiceResponse", "type": "object"}, "VehicleFleetInvoiceCreate": {"additionalProperties": false, "properties": {"description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "vendor": {"title": "Vendor", "type": "string"}, "invoice_number": {"title": "Invoice Number", "type": "string"}, "lines": {"items": {"$ref": "#/components/schemas/VehicleFleetInvoiceLineCreate"}, "title": "Lines", "type": "array"}}, "required": ["date", "vendor", "invoice_number", "lines"], "title": "VehicleFleetInvoiceCreate", "type": "object"}, "VehicleFleetInvoiceLineCreate": {"additionalProperties": false, "properties": {"vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vehicle Id"}, "vehicle_label": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Label"}, "assignment_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignment Id"}, "type": {"title": "Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "currency": {"default": "EUR", "title": "Currency", "type": "string"}}, "required": ["type", "amount"], "title": "VehicleFleetInvoiceLineCreate", "type": "object"}, "VehicleFleetInvoiceExtractedLine": {"additionalProperties": false, "properties": {"vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vehicle Id"}, "vehicle_license_plate": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle License Plate"}, "type": {"title": "Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "currency": {"default": "EUR", "title": "Currency", "type": "string"}}, "required": ["type", "amount"], "title": "VehicleFleetInvoiceExtractedLine", "type": "object"}, "VehicleFleetInvoiceExtractionResponse": {"additionalProperties": false, "properties": {"file_name": {"title": "File Name", "type": "string"}, "vendor": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vendor"}, "invoice_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Invoice Number"}, "date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Currency"}, "total_amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Total Amount"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "duplicate_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duplicate Invoice Id"}, "lines": {"default": [], "items": {"$ref": "#/components/schemas/VehicleFleetInvoiceExtractedLine"}, "title": "Lines", "type": "array"}, "warnings": {"default": [], "items": {"type": "string"}, "title": "Warnings", "type": "array"}}, "required": ["file_name"], "title": "VehicleFleetInvoiceExtractionResponse", "type": "object"}, "VehicleFleetInvoiceLineUpdate": {"additionalProperties": false, "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vehicle Id"}, "vehicle_label": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vehicle Label"}, "assignment_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignment Id"}, "type": {"title": "Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}], "title": "Amount"}, "currency": {"default": "EUR", "title": "Currency", "type": "string"}}, "required": ["type", "amount"], "title": "VehicleFleetInvoiceLineUpdate", "type": "object"}, "VehicleFleetInvoiceUpdate": {"additionalProperties": false, "properties": {"description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Date To"}, "vendor": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vendor"}, "invoice_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Invoice Number"}, "lines": {"anyOf": [{"items": {"$ref": "#/components/schemas/VehicleFleetInvoiceLineUpdate"}, "type": "array"}, {"type": "null"}], "title": "Lines"}}, "title": "VehicleFleetInvoiceUpdate", "type": "object"}, "FileResourceResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "file_id": {"title": "File Id", "type": "integer"}, "resource_id": {"title": "Resource Id", "type": "integer"}, "resource_class": {"title": "Resource Class", "type": "string"}, "extra_data": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Extra Data"}, "file_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "File Name"}}, "required": ["id", "file_id", "resource_id", "resource_class"], "title": "FileResourceResponse", "type": "object"}, "ObdGpsDeviceQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by IMEI", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}}, "title": "ObdGpsDeviceQueryParams", "type": "object"}, "ObdGpsAssignmentVehicle": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "license_plate": {"title": "License Plate", "type": "string"}, "make": {"title": "Make", "type": "string"}, "model": {"title": "Model", "type": "string"}}, "required": ["id", "license_plate", "make", "model"], "title": "ObdGpsAssignmentVehicle", "type": "object"}, "ObdGpsDeviceAssignmentResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "assignee_user": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}]}, "vehicle": {"anyOf": [{"$ref": "#/components/schemas/ObdGpsAssignmentVehicle"}, {"type": "null"}]}, "start_date": {"title": "Start Date", "type": "string"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "End Date"}}, "required": ["id", "start_date"], "title": "ObdGpsDeviceAssignmentResponse", "type": "object"}, "ObdGpsDeviceResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "imei": {"title": "Imei", "type": "string"}, "location_id": {"title": "Location Id", "type": "integer"}, "telematics_provider": {"title": "Telematics Provider", "type": "string"}, "current_assignment": {"anyOf": [{"$ref": "#/components/schemas/ObdGpsDeviceAssignmentResponse"}, {"type": "null"}]}, "live_state": {"anyOf": [{"$ref": "#/components/schemas/NavirecLiveState"}, {"type": "null"}]}, "updated_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Updated At"}}, "required": ["id", "imei", "location_id", "telematics_provider"], "title": "ObdGpsDeviceResponse", "type": "object"}, "ObdGpsDeviceCreate": {"additionalProperties": false, "properties": {"imei": {"title": "Imei", "type": "string"}, "location_id": {"title": "Location Id", "type": "integer"}, "telematics_provider": {"anyOf": [{"enum": ["NAVIREC", "MOTIVE"], "type": "string"}, {"type": "null"}], "title": "Telematics Provider"}}, "required": ["imei", "location_id"], "title": "ObdGpsDeviceCreate", "type": "object"}, "ObdGpsDeviceAssignSchema": {"additionalProperties": false, "properties": {"assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee User Id"}, "vehicle_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vehicle Id"}, "start_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Start Date"}}, "required": ["start_date"], "title": "ObdGpsDeviceAssignSchema", "type": "object"}, "ObdGpsDeviceEndAssignmentSchema": {"additionalProperties": false, "properties": {"end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "End Date"}}, "required": ["end_date"], "title": "ObdGpsDeviceEndAssignmentSchema", "type": "object"}, "NavirecSyncErrorItem": {"additionalProperties": false, "properties": {"imei": {"title": "Imei", "type": "string"}, "reason": {"title": "Reason", "type": "string"}}, "required": ["imei", "reason"], "title": "NavirecSyncErrorItem", "type": "object"}, "NavirecSyncResponse": {"additionalProperties": false, "properties": {"synced": {"title": "Synced", "type": "integer"}, "skipped": {"title": "Skipped", "type": "integer"}, "errors": {"default": [], "items": {"$ref": "#/components/schemas/NavirecSyncErrorItem"}, "title": "Errors", "type": "array"}, "disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Disabled"}}, "required": ["synced", "skipped"], "title": "NavirecSyncResponse", "type": "object"}, "ObdGpsDeviceAssignmentFullResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "device_id": {"title": "Device Id", "type": "integer"}, "assignee_user": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}]}, "vehicle": {"anyOf": [{"$ref": "#/components/schemas/ObdGpsAssignmentVehicle"}, {"type": "null"}]}, "start_date": {"title": "Start Date", "type": "string"}, "end_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "End Date"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}}, "required": ["id", "device_id", "start_date", "created_at"], "title": "ObdGpsDeviceAssignmentFullResponse", "type": "object"}, "ObdGpsDeviceUpdate": {"additionalProperties": false, "properties": {"imei": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Imei"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "telematics_provider": {"anyOf": [{"enum": ["NAVIREC", "MOTIVE"], "type": "string"}, {"type": "null"}], "title": "Telematics Provider"}}, "title": "ObdGpsDeviceUpdate", "type": "object"}, "VehicleMapLocation": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"title": "Type", "type": "string"}, "latitude": {"title": "Latitude", "type": "number"}, "longitude": {"title": "Longitude", "type": "number"}, "vehicle_count": {"title": "Vehicle Count", "type": "integer"}, "vehicles": {"items": {"$ref": "#/components/schemas/VehicleMapLocationVehicle"}, "title": "Vehicles", "type": "array"}}, "required": ["id", "name", "type", "latitude", "longitude", "vehicle_count", "vehicles"], "title": "VehicleMapLocation", "type": "object"}, "VehicleMapLocationVehicle": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "license_plate": {"title": "License Plate", "type": "string"}, "make": {"title": "Make", "type": "string"}, "model": {"title": "Model", "type": "string"}, "type": {"title": "Type", "type": "string"}, "status": {"title": "Status", "type": "string"}}, "required": ["id", "license_plate", "make", "model", "type", "status"], "title": "VehicleMapLocationVehicle", "type": "object"}, "VehicleFleetLocationQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by name", "title": "Search"}}, "title": "VehicleFleetLocationQueryParams", "type": "object"}, "VehicleFleetLocationResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "VehicleFleetLocationResponse", "type": "object"}, "ServiceOrderLineQueryParams": {"additionalProperties": false, "description": "Query parameters for service order lines listing.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by SOL ID, service code, or service description (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix with '-' for descending. Allowed: service_code, service_description, status, quantity", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code (exact match)", "title": "Service Code"}, "activity_date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SOLs with activities on or after this date", "title": "Activity Date From"}, "activity_date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SOLs with activities on or before this date", "title": "Activity Date To"}, "total_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Client-supplied total count from a previous page response. When provided, skips the COUNT query and returns this value as Total-Count.", "title": "Total Count"}}, "title": "ServiceOrderLineQueryParams", "type": "object"}, "ComponentTypeInfo": {"additionalProperties": false, "description": "Nested component type info for service order line response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ComponentTypeInfo", "type": "object"}, "ProjectInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "project_builder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Builder Id"}}, "required": ["id"], "title": "ProjectInfo", "type": "object"}, "ServiceOrderLineResponse": {"additionalProperties": false, "description": "Response schema for a single service order line.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Quantity"}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/TurbineInfo"}, {"type": "null"}]}, "component_type": {"anyOf": [{"$ref": "#/components/schemas/ComponentTypeInfo"}, {"type": "null"}]}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/TurbineComponentInfo"}, {"type": "null"}]}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectInfo"}, {"type": "null"}]}, "assigned_team_lead": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Assigned Team Lead"}, "activity_date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Activity Date From"}, "activity_date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Activity Date To"}}, "required": ["id"], "title": "ServiceOrderLineResponse", "type": "object"}, "TurbineComponentInfo": {"additionalProperties": false, "description": "Nested turbine component info for service order line response.", "properties": {"id": {"title": "Id", "type": "integer"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Serial Number"}}, "required": ["id"], "title": "TurbineComponentInfo", "type": "object"}, "TurbineInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "TurbineInfo", "type": "object"}, "FilterProjectOption": {"additionalProperties": false, "description": "Project option for filters endpoint.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}}, "required": ["id"], "title": "FilterProjectOption", "type": "object"}, "FilterServiceOption": {"additionalProperties": false, "description": "Service option for filters endpoint.", "properties": {"code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["code"], "title": "FilterServiceOption", "type": "object"}, "FilterTurbineOption": {"additionalProperties": false, "description": "Turbine option for filters endpoint.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "FilterTurbineOption", "type": "object"}, "ServiceOrderLineFiltersResponse": {"additionalProperties": false, "description": "Response schema for SOL filters endpoint.", "properties": {"projects": {"items": {"$ref": "#/components/schemas/FilterProjectOption"}, "title": "Projects", "type": "array"}, "turbines": {"items": {"$ref": "#/components/schemas/FilterTurbineOption"}, "title": "Turbines", "type": "array"}, "services": {"items": {"$ref": "#/components/schemas/FilterServiceOption"}, "title": "Services", "type": "array"}}, "required": ["projects", "turbines", "services"], "title": "ServiceOrderLineFiltersResponse", "type": "object"}, "ServiceOrderLineDetailResponse": {"additionalProperties": false, "description": "Detail schema for SOL context used in technician service results view.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Name"}, "turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Component Serial"}, "turbine_component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Component Position"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}}, "required": ["id"], "title": "ServiceOrderLineDetailResponse", "type": "object"}, "WorkorderQueryParams": {"additionalProperties": false, "description": "Query parameters for workorders listing.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by workorder name", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix '-' for desc. Allowed: name, status, planned_start_date, planned_end_date", "title": "Sort"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by SOL ID", "title": "Service Order Line Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status (exact)", "title": "Status"}, "planned_start_date__gte": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned start date on or after this date", "title": "Planned Start Date Gte"}, "planned_start_date__lte": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned start date on or before this date", "title": "Planned Start Date Lte"}}, "title": "WorkorderQueryParams", "type": "object"}, "WorkorderComponentTypeInfo": {"additionalProperties": false, "description": "Nested component type info for workorder response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "WorkorderComponentTypeInfo", "type": "object"}, "WorkorderProjectInfo": {"additionalProperties": false, "description": "Nested project info for workorder response.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}}, "required": ["id"], "title": "WorkorderProjectInfo", "type": "object"}, "WorkorderResponse": {"additionalProperties": false, "description": "Response schema for a single workorder.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/WorkorderTurbineInfo"}, {"type": "null"}]}, "project": {"anyOf": [{"$ref": "#/components/schemas/WorkorderProjectInfo"}, {"type": "null"}]}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_item_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Item Description"}, "component_type": {"anyOf": [{"$ref": "#/components/schemas/WorkorderComponentTypeInfo"}, {"type": "null"}]}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/WorkorderTurbineComponentInfo"}, {"type": "null"}]}, "activities_total": {"default": 0, "title": "Activities Total", "type": "integer"}, "activities_completed": {"default": 0, "title": "Activities Completed", "type": "integer"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}}, "required": ["id"], "title": "WorkorderResponse", "type": "object"}, "WorkorderTurbineComponentInfo": {"additionalProperties": false, "description": "Nested turbine component info for workorder response.", "properties": {"id": {"title": "Id", "type": "integer"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Serial Number"}}, "required": ["id"], "title": "WorkorderTurbineComponentInfo", "type": "object"}, "WorkorderTurbineInfo": {"additionalProperties": false, "description": "Nested turbine info for workorder response.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "WorkorderTurbineInfo", "type": "object"}, "FilterSolOption": {"additionalProperties": false, "description": "SOL option for workorder filters endpoint.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}}, "required": ["id"], "title": "FilterSolOption", "type": "object"}, "WorkorderFiltersResponse": {"additionalProperties": false, "description": "Response schema for workorder filters endpoint.", "properties": {"projects": {"items": {"$ref": "#/components/schemas/FilterProjectOption"}, "title": "Projects", "type": "array"}, "statuses": {"items": {"type": "string"}, "title": "Statuses", "type": "array"}, "service_order_lines": {"items": {"$ref": "#/components/schemas/FilterSolOption"}, "title": "Service Order Lines", "type": "array"}, "turbines": {"items": {"$ref": "#/components/schemas/FilterTurbineOption"}, "title": "Turbines", "type": "array"}}, "required": ["projects", "statuses", "service_order_lines", "turbines"], "title": "WorkorderFiltersResponse", "type": "object"}, "SolActivitiesQueryParams": {"additionalProperties": false, "description": "Query parameters for SOL activities listing.", "properties": {"sol_id": {"description": "Service Order Line ID (required)", "title": "Sol Id", "type": "integer"}}, "required": ["sol_id"], "title": "SolActivitiesQueryParams", "type": "object"}, "SolActivitiesPageResponse": {"additionalProperties": false, "description": "Response schema for SOL activities page endpoint.", "properties": {"activities": {"items": {"$ref": "#/components/schemas/SolActivityResponse"}, "title": "Activities", "type": "array"}, "assigned_workorder_ids": {"items": {"type": "integer"}, "title": "Assigned Workorder Ids", "type": "array"}, "sol_info": {"anyOf": [{"$ref": "#/components/schemas/SolInfo"}, {"type": "null"}]}}, "required": ["activities", "assigned_workorder_ids"], "title": "SolActivitiesPageResponse", "type": "object"}, "SolActivityAssignedResources": {"additionalProperties": false, "description": "Grouped assignment details for an activity.", "properties": {"robot_sets": {"default": [], "items": {"type": "string"}, "title": "Robot Sets", "type": "array"}, "team_leads": {"default": [], "items": {"type": "string"}, "title": "Team Leads", "type": "array"}, "team_members": {"default": [], "items": {"type": "string"}, "title": "Team Members", "type": "array"}, "supervisors": {"default": [], "items": {"type": "string"}, "title": "Supervisors", "type": "array"}}, "title": "SolActivityAssignedResources", "type": "object"}, "SolActivityResponse": {"additionalProperties": false, "description": "Response schema for a single activity in the SOL activities view.", "properties": {"id": {"title": "Id", "type": "integer"}, "row_key": {"title": "Row Key", "type": "string"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "team_robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Team Robot Set Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "workorder_id": {"title": "Workorder Id", "type": "integer"}, "workorder_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workorder Name"}, "workorder_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workorder Status"}, "workorder_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workorder Type"}, "component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Serial"}, "component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Position"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Type Name"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Timezone"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}, "activity_resources": {"default": [], "items": {"$ref": "#/components/schemas/WorkorderActivityResourceLink"}, "title": "Activity Resources", "type": "array"}, "assigned_resources": {"anyOf": [{"$ref": "#/components/schemas/SolActivityAssignedResources"}, {"type": "null"}]}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "overtime_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Overtime Reason"}, "is_delay": {"default": false, "title": "Is Delay", "type": "boolean"}, "delay_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Delay Type Name"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}, "estimated_duration": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration"}}, "required": ["id", "row_key", "workorder_id"], "title": "SolActivityResponse", "type": "object"}, "SolInfo": {"additionalProperties": false, "description": "SOL context info for the SOL activities page header.", "properties": {"service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Quantity"}, "scope_change": {"anyOf": [{"$ref": "#/components/schemas/SolScopeChange"}, {"type": "null"}]}, "scope_changes": {"default": [], "items": {"$ref": "#/components/schemas/SolScopeChange"}, "title": "Scope Changes", "type": "array"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Timezone"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "project_manager_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Manager Name"}, "project_manager_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Manager Email"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "daily_report_robots": {"default": [], "items": {"type": "string"}, "title": "Daily Report Robots", "type": "array"}, "daily_report_team_leads": {"default": [], "items": {"type": "string"}, "title": "Daily Report Team Leads", "type": "array"}, "daily_report_technicians": {"default": [], "items": {"type": "string"}, "title": "Daily Report Technicians", "type": "array"}, "daily_report_supervisors": {"default": [], "items": {"type": "string"}, "title": "Daily Report Supervisors", "type": "array"}, "receive_daily_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Receive Daily Reports"}, "draft_last_submitted_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Draft Last Submitted At"}, "draft_last_submitted_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Draft Last Submitted By"}, "draft_submissions_by_date": {"anyOf": [{"additionalProperties": {"additionalProperties": {"anyOf": [{"type": "string"}, {"type": "null"}]}, "type": "object"}, "type": "object"}, {"type": "null"}], "title": "Draft Submissions By Date"}}, "title": "SolInfo", "type": "object"}, "SolScopeChange": {"additionalProperties": false, "description": "Scope-change context for SOL/workorder header banners.\n\n``turbine_component`` is set for per-blade changes (the source line\nstays active and only that blade's work moved to the new SOL);\n``linked_sol`` may be null when the counterpart line is gone.", "properties": {"id": {"title": "Id", "type": "integer"}, "role": {"title": "Role", "type": "string"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/SolScopeChangeComponent"}, {"type": "null"}]}, "linked_sol": {"anyOf": [{"$ref": "#/components/schemas/SolScopeChangeLinkedSol"}, {"type": "null"}]}}, "required": ["id", "role"], "title": "SolScopeChange", "type": "object"}, "SolScopeChangeComponent": {"additionalProperties": false, "description": "The blade a per-blade scope change applies to.", "properties": {"id": {"title": "Id", "type": "integer"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Position"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Serial Number"}}, "required": ["id"], "title": "SolScopeChangeComponent", "type": "object"}, "SolScopeChangeLinkedSol": {"additionalProperties": false, "description": "The counterpart SOL on the other side of a scope change.", "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "required": ["id"], "title": "SolScopeChangeLinkedSol", "type": "object"}, "WorkorderActivityResourceLink": {"additionalProperties": false, "description": "Resource assignment row on a workorder activity.\n\nMirrors the dict shape returned by\n:py:attr:`dispatch.models.WorkorderActivity.activity_resources` (one entry\nper row in the ``dispatch.workorder_activity_resources`` junction table).", "properties": {"id": {"title": "Id", "type": "integer"}, "resource_id": {"title": "Resource Id", "type": "integer"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Lead"}, "resource_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Full Name"}, "resource_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Email"}}, "required": ["id", "resource_id"], "title": "WorkorderActivityResourceLink", "type": "object"}, "AvailableResourceInfo": {"additionalProperties": false, "description": "Available resource option for activity assignment edit.", "properties": {"id": {"title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Full Name"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}}, "required": ["id"], "title": "AvailableResourceInfo", "type": "object"}, "WorkorderDetailResponse": {"additionalProperties": false, "description": "Response schema for a single workorder detail.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Serial"}, "component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Position"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Name"}, "resource_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Set Name"}, "resources": {"default": [], "items": {"$ref": "#/components/schemas/WorkorderResourceInfo"}, "title": "Resources", "type": "array"}, "available_robot_sets": {"default": [], "items": {"$ref": "#/components/schemas/WorkorderRobotSetInfo"}, "title": "Available Robot Sets", "type": "array"}, "available_resources": {"default": [], "items": {"$ref": "#/components/schemas/AvailableResourceInfo"}, "title": "Available Resources", "type": "array"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Timezone"}, "is_assigned": {"default": false, "title": "Is Assigned", "type": "boolean"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "scope_change": {"anyOf": [{"$ref": "#/components/schemas/SolScopeChange"}, {"type": "null"}]}}, "required": ["id"], "title": "WorkorderDetailResponse", "type": "object"}, "WorkorderResourceInfo": {"additionalProperties": false, "description": "Nested resource info for workorder detail response.", "properties": {"id": {"title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Full Name"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}, "is_lead": {"default": false, "title": "Is Lead", "type": "boolean"}}, "required": ["id"], "title": "WorkorderResourceInfo", "type": "object"}, "WorkorderRobotSetInfo": {"additionalProperties": false, "description": "Available robot set option for workorder activity assignments.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "WorkorderRobotSetInfo", "type": "object"}, "AvailableActivityResponse": {"additionalProperties": false, "description": "Response schema for an available service item activity.", "properties": {"id": {"title": "Id", "type": "integer"}, "description": {"title": "Description", "type": "string"}, "estimated_duration": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}}, "required": ["id", "description"], "title": "AvailableActivityResponse", "type": "object"}, "ResourcePresetMember": {"additionalProperties": false, "description": "A single member of a resource preset (ProjectResourceSet).", "properties": {"resource_id": {"title": "Resource Id", "type": "integer"}, "resource_name": {"title": "Resource Name", "type": "string"}, "is_lead": {"default": false, "title": "Is Lead", "type": "boolean"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}}, "required": ["resource_id", "resource_name"], "title": "ResourcePresetMember", "type": "object"}, "ResourcePresetResponse": {"additionalProperties": false, "description": "A project resource set available as a team preset.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "members": {"items": {"$ref": "#/components/schemas/ResourcePresetMember"}, "title": "Members", "type": "array"}}, "required": ["id", "name", "members"], "title": "ResourcePresetResponse", "type": "object"}, "DashboardSummaryQueryParams": {"additionalProperties": false, "description": "Query parameters for operations dashboard summary.", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/after this date", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/before this date", "title": "End Date"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}}, "title": "DashboardSummaryQueryParams", "type": "object"}, "DashboardSummaryResponse": {"additionalProperties": false, "description": "Operations dashboard summary KPI payload.", "properties": {"total_results": {"title": "Total Results", "type": "integer"}, "auto_verified": {"title": "Auto Verified", "type": "integer"}, "pending_operator": {"title": "Pending Operator", "type": "integer"}, "pending_missing_standard": {"title": "Pending Missing Standard", "type": "integer"}, "pending_missing_threshold_match": {"title": "Pending Missing Threshold Match", "type": "integer"}, "pending_missing_required_fields": {"title": "Pending Missing Required Fields", "type": "integer"}, "pending_invalid_value": {"title": "Pending Invalid Value", "type": "integer"}}, "required": ["total_results", "auto_verified", "pending_operator", "pending_missing_standard", "pending_missing_threshold_match", "pending_missing_required_fields", "pending_invalid_value"], "title": "DashboardSummaryResponse", "type": "object"}, "DashboardQueueQueryParams": {"additionalProperties": false, "description": "Query parameters for operations dashboard queue.", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/after this date", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/before this date", "title": "End Date"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}, "validation_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by validation reason: missing_required_fields, missing_standard, missing_threshold_match, invalid_value, condition_nok, multiple_readings", "title": "Validation Reason"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by created_at or service_code. Prefix with '-' for descending.", "title": "Sort"}}, "title": "DashboardQueueQueryParams", "type": "object"}, "DashboardQueueItem": {"additionalProperties": false, "description": "One queue row for operator review.", "properties": {"result": {"$ref": "#/components/schemas/ServiceResultRecord"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Component Serial"}, "workorder_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Workorder Name"}}, "required": ["result"], "title": "DashboardQueueItem", "type": "object"}, "ServiceResultRecord": {"additionalProperties": false, "description": "Normalized service result record for dashboard and detail endpoints.", "properties": {"id": {"title": "Id", "type": "integer"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}, "turbine_id": {"title": "Turbine Id", "type": "integer"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Template Id"}, "template_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Template Code"}, "standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Standard Id"}, "standard_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Standard Name"}, "result_threshold_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Result Threshold Id"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "data": {"title": "Data", "type": "object"}, "template": {"anyOf": [{"$ref": "#/components/schemas/ServiceResultTemplateInfo"}, {"type": "null"}]}, "standard": {"anyOf": [{"$ref": "#/components/schemas/ServiceResultStandardInfo"}, {"type": "null"}]}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/ServiceResultTurbineComponentInfo"}, {"type": "null"}]}, "workorder": {"anyOf": [{"$ref": "#/components/schemas/ServiceResultWorkorderInfo"}, {"type": "null"}]}, "validation_state": {"title": "Validation State", "type": "string"}, "validation_reasons": {"items": {"type": "string"}, "title": "Validation Reasons", "type": "array"}}, "required": ["id", "turbine_id", "created_at", "updated_at", "data", "validation_state", "validation_reasons"], "title": "ServiceResultRecord", "type": "object"}, "ServiceResultStandardInfo": {"additionalProperties": false, "description": "Nested standard metadata for a service result row.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "key": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Key"}}, "required": ["id"], "title": "ServiceResultStandardInfo", "type": "object"}, "ServiceResultTemplateInfo": {"additionalProperties": false, "description": "Nested template metadata for a service result row.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}}, "required": ["id"], "title": "ServiceResultTemplateInfo", "type": "object"}, "ServiceResultTurbineComponentInfo": {"additionalProperties": false, "description": "Nested turbine component metadata for a service result row.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "ServiceResultTurbineComponentInfo", "type": "object"}, "ServiceResultWorkorderInfo": {"additionalProperties": false, "description": "Nested workorder metadata for a service result row.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "is_derived": {"default": false, "title": "Is Derived", "type": "boolean"}}, "required": ["id"], "title": "ServiceResultWorkorderInfo", "type": "object"}, "ServiceResultListQueryParams": {"additionalProperties": false, "description": "Query parameters for SOL service results listing.", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/after this date", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter results created on/before this date", "title": "End Date"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by template ID", "title": "Template Id"}, "standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by standard ID", "title": "Standard Id"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by workorder ID", "title": "Workorder Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine component ID", "title": "Turbine Component Id"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.side (for example: SUCTION_SIDE, PRESSURE_SIDE)", "title": "Side"}, "condition": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.condition (for example: OK, NOK)", "title": "Condition"}, "result_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.status (for example: CLOGGED, CLEANED)", "title": "Result Status"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by data.comment (case-insensitive contains)", "title": "Comment"}, "open": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.open boolean value", "title": "Open"}, "no_reading": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.no_reading boolean value", "title": "No Reading"}, "test_failed": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.test_failed boolean value", "title": "Test Failed"}, "oxidation_removed": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by data.is_oxidation_removal boolean value", "title": "Oxidation Removed"}, "validation_state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by validation state: AUTO_VERIFIED, PENDING_OPERATOR", "title": "Validation State"}, "validation_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by validation reason: missing_required_fields, missing_standard, missing_threshold_match, invalid_value, condition_nok, multiple_readings", "title": "Validation Reason"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by result id, template code, threshold name, or standard", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by created_at, updated_at, id, template_code, standard_name, workorder_id, turbine_component_id, result_threshold_id, or reading. Prefix with '-' for descending.", "title": "Sort"}}, "title": "ServiceResultListQueryParams", "type": "object"}, "ServiceResultMutationResponse": {"additionalProperties": false, "description": "Mutation response for create/update service result endpoints.", "properties": {"result": {"$ref": "#/components/schemas/ServiceResultRecord"}}, "required": ["result"], "title": "ServiceResultMutationResponse", "type": "object"}, "ServiceResultCreateInput": {"additionalProperties": false, "description": "Create payload for service results from technician SOL flow.", "properties": {"workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Template Id"}, "standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Standard Id"}, "data": {"title": "Data", "type": "object"}}, "required": ["data"], "title": "ServiceResultCreateInput", "type": "object"}, "BladeComponent": {"additionalProperties": false, "description": "Turbine blade component reference for BCL upload tabs.", "properties": {"id": {"title": "Id", "type": "integer"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Serial Number"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Position"}}, "required": ["id"], "title": "BladeComponent", "type": "object"}, "ResultCaptureContextResponse": {"additionalProperties": false, "description": "Context payload for technician result capture drawer/form.", "properties": {"service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Component Serial"}, "blade_components": {"default": [], "items": {"$ref": "#/components/schemas/BladeComponent"}, "title": "Blade Components", "type": "array"}, "templates": {"items": {"$ref": "#/components/schemas/ResultCaptureTemplate"}, "title": "Templates", "type": "array"}, "selected_template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Selected Template Id"}, "latest_result": {"anyOf": [{"$ref": "#/components/schemas/ServiceResultRecord"}, {"type": "null"}]}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "stage": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Stage"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Name"}, "completed_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Completed By"}, "completed_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Completed Date"}, "finalized_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Finalized By"}, "finalized_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Finalized By Name"}, "service_finalized_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Finalized Date"}}, "required": ["service_order_line_id", "templates"], "title": "ResultCaptureContextResponse", "type": "object"}, "ResultCaptureStandard": {"additionalProperties": false, "description": "Standard option for result capture.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "key": {"title": "Key", "type": "string"}, "type": {"title": "Type", "type": "string"}}, "required": ["id", "name", "key", "type"], "title": "ResultCaptureStandard", "type": "object"}, "ResultCaptureTemplate": {"additionalProperties": false, "description": "Template definition for result capture context.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "fields": {"items": {"$ref": "#/components/schemas/ResultCaptureTemplateField"}, "title": "Fields", "type": "array"}, "standards": {"items": {"$ref": "#/components/schemas/ResultCaptureStandard"}, "title": "Standards", "type": "array"}, "thresholds": {"items": {"$ref": "#/components/schemas/ResultCaptureThreshold"}, "title": "Thresholds", "type": "array"}}, "required": ["id", "code", "fields", "standards", "thresholds"], "title": "ResultCaptureTemplate", "type": "object"}, "ResultCaptureTemplateField": {"additionalProperties": false, "description": "Field configuration for dynamic result entry form.", "properties": {"id": {"title": "Id", "type": "integer"}, "key": {"title": "Key", "type": "string"}, "label": {"title": "Label", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "field_type": {"title": "Field Type", "type": "string"}, "is_required": {"title": "Is Required", "type": "boolean"}, "sort_order": {"title": "Sort Order", "type": "integer"}, "unit": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Unit"}, "options": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Options"}, "default_value": {"anyOf": [{}, {"type": "null"}], "title": "Default Value"}}, "required": ["id", "key", "label", "field_type", "is_required", "sort_order"], "title": "ResultCaptureTemplateField", "type": "object"}, "ResultCaptureThreshold": {"additionalProperties": false, "description": "Threshold definition exposed to frontend for transparency.", "properties": {"id": {"title": "Id", "type": "integer"}, "standard_id": {"title": "Standard Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "value_from": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Value From"}, "value_to": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Value To"}}, "required": ["id", "standard_id", "name"], "title": "ResultCaptureThreshold", "type": "object"}, "FinalizeServiceResponse": {"additionalProperties": false, "description": "Response after finalizing a service order line.", "properties": {"service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}, "status": {"title": "Status", "type": "string"}, "completed_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Completed By"}, "completed_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Completed Date"}}, "required": ["service_order_line_id", "status"], "title": "FinalizeServiceResponse", "type": "object"}, "ServiceResultUpdateInput": {"additionalProperties": false, "description": "Patch payload for service result records.", "properties": {"workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Template Id"}, "standard_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Standard Id"}, "data": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Data"}}, "title": "ServiceResultUpdateInput", "type": "object"}, "SolCleaningImagesResponse": {"additionalProperties": false, "description": "SOL-level cleaning image references keyed by category.", "properties": {"cleaning_images": {"additionalProperties": {"items": {"type": "string"}, "type": "array"}, "title": "Cleaning Images", "type": "object"}}, "required": ["cleaning_images"], "title": "SolCleaningImagesResponse", "type": "object"}, "SolCleaningImagesInput": {"additionalProperties": false, "description": "Patch payload for SOL cleaning images.", "properties": {"cleaning_images": {"additionalProperties": {"items": {"type": "string"}, "type": "array"}, "title": "Cleaning Images", "type": "object"}}, "required": ["cleaning_images"], "title": "SolCleaningImagesInput", "type": "object"}, "DailyReportSolQueryParams": {"additionalProperties": false, "description": "Query parameters for the SOL preview table on the daily reports page.", "properties": {"project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (optional)", "title": "Project Id"}, "project_manager_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project manager user ID", "title": "Project Manager Id"}, "robot_set_ids": {"description": "Robot set IDs", "items": {"type": "integer"}, "title": "Robot Set Ids", "type": "array"}, "statuses": {"description": "Filter by service order line status (the 'Status Now' column). Repeatable / comma-separated. Allowed: NOT_STARTED, IN_PROGRESS, FIELD_COMPLETED, COMPLETED, CANCELLED.", "items": {"type": "string"}, "title": "Statuses", "type": "array"}, "date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Activity date", "title": "Date"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field (snake_case). Prefix with '-' for descending. Supported: id, service_code, actual_status, report_status, customer_name, project_code, turbine_name, location_name, activity_from, activity_to, daily_report_last_sent_at.", "title": "Sort"}}, "title": "DailyReportSolQueryParams", "type": "object"}, "DailyReportSolResponse": {"additionalProperties": false, "description": "Response schema for a single SOL in the daily reports preview.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "actual_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Actual Status"}, "actual_status_changed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Actual Status Changed At"}, "report_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Report Status"}, "completed_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Name"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "project_manager_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Manager Id"}, "project_manager_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Manager Name"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "component_label": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Label"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Timezone"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "current_team_lead": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Current Team Lead"}, "daily_report_last_sent_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Daily Report Last Sent At"}, "daily_report_last_sent_by_user": {"anyOf": [{"$ref": "#/components/schemas/DailyReportSubmittedByUser"}, {"type": "null"}]}, "selected_date_last_sent_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Selected Date Last Sent At"}, "selected_date_last_sent_by_user": {"anyOf": [{"$ref": "#/components/schemas/DailyReportSubmittedByUser"}, {"type": "null"}]}, "selected_date_draft_submitted_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Selected Date Draft Submitted At"}, "selected_date_draft_submitted_by_user": {"anyOf": [{"$ref": "#/components/schemas/DailyReportSubmittedByUser"}, {"type": "null"}]}, "activity_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Activity From"}, "activity_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Activity To"}, "available_report_dates": {"items": {"format": "date", "type": "string"}, "title": "Available Report Dates", "type": "array"}, "activity_report_dates": {"items": {"format": "date", "type": "string"}, "title": "Activity Report Dates", "type": "array"}, "sent_report_dates": {"items": {"format": "date", "type": "string"}, "title": "Sent Report Dates", "type": "array"}, "is_report_eligible": {"default": false, "title": "Is Report Eligible", "type": "boolean"}, "report_recipients": {"items": {"type": "string"}, "title": "Report Recipients", "type": "array"}, "receive_daily_reports": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Pre-job \u2192 Billing & Reporting \u2192 Reporting answer to 'Would you like to receive daily reports?'. NULL means never answered and behaves as yes. False blocks sending the report to the client.", "title": "Receive Daily Reports"}, "recipient_source": {"default": "none", "description": "Where the client recipients came from: 'pre_job' (Pre-job Reporting selection), 'rfi' (RFI Contacts report recipients, used when no Pre-job selection is saved) or 'none'.", "title": "Recipient Source", "type": "string"}}, "required": ["id"], "title": "DailyReportSolResponse", "type": "object"}, "DailyReportSubmittedByUser": {"additionalProperties": false, "description": "Submitted-by user identity for selected-date draft metadata.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "DailyReportSubmittedByUser", "type": "object"}, "DownloadReportRequest": {"additionalProperties": false, "description": "Request body for generating a daily report.", "properties": {"project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (optional when all selected SOLs belong to one project)", "title": "Project Id"}, "robot_set_ids": {"description": "List of robot set IDs", "items": {"type": "integer"}, "title": "Robot Set Ids", "type": "array"}, "date": {"description": "Report date (YYYY-MM-DD)", "format": "date", "title": "Date", "type": "string"}, "format": {"default": "pdf", "description": "Output format (pdf, html)", "title": "Format", "type": "string"}, "service_order_line_ids": {"description": "Selected service order line IDs (empty = all matching)", "items": {"type": "integer"}, "title": "Service Order Line Ids", "type": "array"}, "submit_draft": {"default": false, "description": "When true, persist a draft-submission log for selected SOLs.", "title": "Submit Draft", "type": "boolean"}}, "required": ["date"], "title": "DownloadReportRequest", "type": "object"}, "SendReportResponse": {"additionalProperties": false, "description": "Response payload for successful daily report send action.", "properties": {"success": {"title": "Success", "type": "boolean"}, "message": {"title": "Message", "type": "string"}, "recipients_count": {"title": "Recipients Count", "type": "integer"}, "recipient_emails": {"items": {"type": "string"}, "title": "Recipient Emails", "type": "array"}}, "required": ["success", "message", "recipients_count"], "title": "SendReportResponse", "type": "object"}, "SendReportRequest": {"additionalProperties": false, "description": "Request body for sending a daily report via the reporting engine.", "properties": {"project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID (optional when all selected SOLs belong to one project)", "title": "Project Id"}, "robot_set_ids": {"description": "List of robot set IDs", "items": {"type": "integer"}, "title": "Robot Set Ids", "type": "array"}, "date": {"description": "Report date (YYYY-MM-DD)", "format": "date", "title": "Date", "type": "string"}, "format": {"default": "pdf", "description": "Output format (pdf, docx)", "title": "Format", "type": "string"}, "service_order_line_ids": {"description": "Selected service order line IDs (empty = all matching)", "items": {"type": "integer"}, "title": "Service Order Line Ids", "type": "array"}, "file_token": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "X-File-Token from the download step. When provided the reporting engine attaches the exact cached file without re-rendering.", "title": "File Token"}, "report_token": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Report snapshot token (X-Report-Token) returned by the download step.", "title": "Report Token"}}, "required": ["date"], "title": "SendReportRequest", "type": "object"}, "FinalReportRequest": {"additionalProperties": false, "description": "Request body for generating a final report for a single SOL.", "properties": {"service_order_line_id": {"description": "Service order line ID", "title": "Service Order Line Id", "type": "integer"}, "format": {"default": "pdf", "description": "Output format (pdf, html)", "title": "Format", "type": "string"}, "exclude_fields": {"description": "Optional report field names to exclude (e.g. comments, description)", "items": {"type": "string"}, "title": "Exclude Fields", "type": "array"}}, "required": ["service_order_line_id"], "title": "FinalReportRequest", "type": "object"}, "FinalReportStateQueryParams": {"additionalProperties": false, "description": "Query params for the final-report modal state endpoint.", "properties": {"service_order_line_id": {"description": "Service order line ID", "title": "Service Order Line Id", "type": "integer"}}, "required": ["service_order_line_id"], "title": "FinalReportStateQueryParams", "type": "object"}, "FinalReportGenerationSummary": {"additionalProperties": false, "description": "A single final-report generation, used in the modal state payload.", "properties": {"generation_id": {"title": "Generation Id", "type": "integer"}, "status": {"title": "Status", "type": "string"}, "generated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Generated At"}, "generated_by_user": {"anyOf": [{"$ref": "#/components/schemas/DailyReportSubmittedByUser"}, {"type": "null"}]}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}}, "required": ["generation_id", "status"], "title": "FinalReportGenerationSummary", "type": "object"}, "FinalReportStateResponse": {"additionalProperties": false, "description": "State the Final Report modal needs on open.\n\n``latest_completed`` drives the \"Previously generated report\" button and its\ntooltip; ``in_progress`` lets the modal resume the \"Generating...\" state.", "properties": {"latest_completed": {"anyOf": [{"$ref": "#/components/schemas/FinalReportGenerationSummary"}, {"type": "null"}]}, "in_progress": {"anyOf": [{"$ref": "#/components/schemas/FinalReportGenerationSummary"}, {"type": "null"}]}}, "title": "FinalReportStateResponse", "type": "object"}, "DispatchServiceQuery": {"additionalProperties": false, "description": "Query params for listing dispatch services.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}}, "title": "DispatchServiceQuery", "type": "object"}, "DispatchService": {"additionalProperties": false, "description": "Dispatch service.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "is_configured": {"title": "Is Configured", "type": "boolean"}}, "required": ["id", "is_configured"], "title": "DispatchService", "type": "object"}, "ServiceItemQuery": {"additionalProperties": false, "description": "Query params for listing service items.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}}, "title": "ServiceItemQuery", "type": "object"}, "ServiceItem": {"additionalProperties": false, "description": "Dispatch service item.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "component": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}, "service": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}}, "required": ["id", "code"], "title": "ServiceItem", "type": "object"}, "ServiceItemActivityQuery": {"additionalProperties": false, "description": "Query params for listing service item activities.", "properties": {"service_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}}, "title": "ServiceItemActivityQuery", "type": "object"}, "ServiceItemActivity": {"additionalProperties": false, "description": "Dispatch service item activity.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "requires_robot_set": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Requires Robot Set"}, "estimated_duration": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}, "instructions": {"default": [], "items": {"$ref": "#/components/schemas/ServiceItemActivityInstruction"}, "title": "Instructions", "type": "array"}}, "required": ["id"], "title": "ServiceItemActivity", "type": "object"}, "ServiceItemActivityAttachment": {"additionalProperties": false, "description": "File (image or video) attached to a service-item-activity instruction.\n\nMirrors the GraphQL `ServiceItemActivityAttachment` type. `url` is\nan authenticated proxy URL through `/api/files/{id}/download` \u2014 the\nunderlying GCS bucket stays private and the URL itself does not\nexpire.", "properties": {"id": {"title": "Id", "type": "integer"}, "caption": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Caption"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "file_name": {"title": "File Name", "type": "string"}, "file_type": {"title": "File Type", "type": "string"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}}, "required": ["id", "file_name", "file_type"], "title": "ServiceItemActivityAttachment", "type": "object"}, "ServiceItemActivityInstruction": {"additionalProperties": false, "description": "One ordered procedure step on a service-item-activity.", "properties": {"id": {"title": "Id", "type": "integer"}, "title": {"title": "Title", "type": "string"}, "body": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Body"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/ServiceItemActivityAttachment"}, "title": "Attachments", "type": "array"}, "links": {"default": [], "items": {"$ref": "#/components/schemas/ServiceItemActivityInstructionLink"}, "title": "Links", "type": "array"}}, "required": ["id", "title"], "title": "ServiceItemActivityInstruction", "type": "object"}, "ServiceItemActivityInstructionLink": {"additionalProperties": false, "description": "Web link on a service-item-activity instruction.", "properties": {"id": {"title": "Id", "type": "integer"}, "url": {"title": "Url", "type": "string"}, "label": {"title": "Label", "type": "string"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}}, "required": ["id", "url", "label"], "title": "ServiceItemActivityInstructionLink", "type": "object"}, "ServiceOrderQuery": {"additionalProperties": false, "description": "Query params for listing service orders.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "windpark_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}}, "title": "ServiceOrderQuery", "type": "object"}, "ServiceOrderHeader": {"additionalProperties": false, "description": "Dispatch service order header.", "properties": {"id": {"title": "Id", "type": "integer"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sales Order Id"}, "project_id": {"title": "Project Id", "type": "integer"}, "project_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Name"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "windpark_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "client_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Client Name"}, "service_order_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Service Order Date"}, "service_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Order Number"}, "service_order_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Order Type"}, "project_manager_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Manager User Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "required": ["id", "project_id", "customer_id"], "title": "ServiceOrderHeader", "type": "object"}, "ServiceOrderHeaderInput": {"additionalProperties": false, "description": "Payload for creating/updating service order headers.", "properties": {"sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sales Order Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "project_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Name"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "windpark_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "client_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Client Name"}, "service_order_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Service Order Date"}, "service_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Order Number"}, "service_order_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Order Type"}, "project_manager_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Manager User Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "title": "ServiceOrderHeaderInput", "type": "object"}, "ServiceOrderClientCount": {"additionalProperties": false, "description": "Count of service orders by client.", "properties": {"client_name": {"title": "Client Name", "type": "string"}, "count": {"title": "Count", "type": "integer"}}, "required": ["client_name", "count"], "title": "ServiceOrderClientCount", "type": "object"}, "ServiceOrderSummary": {"additionalProperties": false, "description": "Service order summary response.", "properties": {"total": {"title": "Total", "type": "integer"}, "by_type": {"items": {"$ref": "#/components/schemas/ServiceOrderTypeCount"}, "title": "By Type", "type": "array"}, "by_client": {"items": {"$ref": "#/components/schemas/ServiceOrderClientCount"}, "title": "By Client", "type": "array"}}, "required": ["total", "by_type", "by_client"], "title": "ServiceOrderSummary", "type": "object"}, "ServiceOrderTypeCount": {"additionalProperties": false, "description": "Count of service orders by type.", "properties": {"service_order_type": {"title": "Service Order Type", "type": "string"}, "count": {"title": "Count", "type": "integer"}}, "required": ["service_order_type", "count"], "title": "ServiceOrderTypeCount", "type": "object"}, "ServiceOrderLineQuery": {"additionalProperties": false, "description": "Query params for listing service order lines.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_scope_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Scope Item Id"}, "original_sol_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Original Sol Id"}, "billable": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Billable"}}, "title": "ServiceOrderLineQuery", "type": "object"}, "ServiceOrderLine": {"additionalProperties": false, "description": "Dispatch service order line.", "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "service_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order"}, "service": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Quantity"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "sales_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sales Order Line Id"}, "project_scope_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Scope Item Id"}, "required_qualifications": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Required Qualifications"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "stage": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Stage"}, "completed_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Completed By"}, "completed_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Completed Date"}, "original_sol_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Original Sol Id"}, "billable": {"default": true, "title": "Billable", "type": "boolean"}}, "required": ["id"], "title": "ServiceOrderLine", "type": "object"}, "ServiceOrderLineInput": {"additionalProperties": false, "description": "Payload for creating/updating service order lines.", "properties": {"number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "service_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order"}, "service": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Quantity"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "sales_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sales Order Line Id"}, "project_scope_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Scope Item Id"}, "required_qualifications": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Required Qualifications"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "stage": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Stage"}, "original_sol_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Original Sol Id"}, "billable": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Billable"}}, "title": "ServiceOrderLineInput", "type": "object"}, "WorkorderQuery": {"additionalProperties": false, "description": "Query params for listing workorders.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "windpark_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "planned_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime"}, "planned_start_datetime__gte": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime Gte"}, "planned_start_datetime__lte": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime Lte"}}, "title": "WorkorderQuery", "type": "object"}, "Workorder": {"additionalProperties": false, "description": "Dispatch workorder.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order"}, "service_order_line": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "planned_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime"}, "planned_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End Datetime"}, "windpark_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Internal"}, "is_optional": {"default": false, "title": "Is Optional", "type": "boolean"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "status_change_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Change By"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "mandatory_start_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Mandatory Start Date"}, "mandatory_due_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Mandatory Due Date"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee User Id"}, "activities_total": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activities Total"}, "activities_completed": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activities Completed"}}, "required": ["id"], "title": "Workorder", "type": "object"}, "AdminWorkorderActivityInput": {"additionalProperties": false, "description": "Input for admin workorder activities (simplified).", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "activity_description": {"title": "Activity Description", "type": "string"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Preset Id"}, "team": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Team"}}, "required": ["activity_description"], "title": "AdminWorkorderActivityInput", "type": "object"}, "WorkorderInput": {"additionalProperties": false, "description": "Payload for creating/updating workorders.", "properties": {"service_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order"}, "service_order_line": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "planned_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime"}, "planned_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End Datetime"}, "windpark_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Windpark Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Internal"}, "is_rework": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Rework"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "status_change_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Change By"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "mandatory_start_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Mandatory Start Date"}, "mandatory_due_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Mandatory Due Date"}, "assignee_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee User Id"}, "activities": {"anyOf": [{"items": {"$ref": "#/components/schemas/AdminWorkorderActivityInput"}, "type": "array"}, {"type": "null"}], "title": "Activities"}}, "title": "WorkorderInput", "type": "object"}, "WorkorderSummary": {"additionalProperties": false, "description": "Workorder summary response.", "properties": {"total": {"title": "Total", "type": "integer"}, "by_status": {"items": {"type": "object"}, "title": "By Status", "type": "array"}, "by_type": {"items": {"type": "object"}, "title": "By Type", "type": "array"}}, "required": ["total", "by_status", "by_type"], "title": "WorkorderSummary", "type": "object"}, "WorkorderActivityCount": {"additionalProperties": false, "description": "Workorder activity count.", "properties": {"workorder_id": {"title": "Workorder Id", "type": "integer"}, "count": {"title": "Count", "type": "integer"}}, "required": ["workorder_id", "count"], "title": "WorkorderActivityCount", "type": "object"}, "WorkorderActivityCountsResponse": {"additionalProperties": false, "description": "Workorder activity counts response.", "properties": {"results": {"items": {"$ref": "#/components/schemas/WorkorderActivityCount"}, "title": "Results", "type": "array"}}, "required": ["results"], "title": "WorkorderActivityCountsResponse", "type": "object"}, "WorkorderActivityQuery": {"additionalProperties": false, "description": "Query params for listing workorder activities.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "service_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Id"}, "service_item_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Activity Id"}}, "title": "WorkorderActivityQuery", "type": "object"}, "WorkorderActivity": {"additionalProperties": false, "description": "Dispatch workorder activity.", "properties": {"id": {"title": "Id", "type": "integer"}, "workorder": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "service_item_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Activity Id"}, "portal_service_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Portal Service Activity Id"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}, "team_lead_resource_ids": {"default": [], "items": {"type": "integer"}, "title": "Team Lead Resource Ids", "type": "array"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Internal"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "status_change_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Change By"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}, "estimated_duration": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration"}}, "required": ["id"], "title": "WorkorderActivity", "type": "object"}, "WorkorderActivityCreateInput": {"additionalProperties": false, "description": "Payload for creating a workorder activity.\n\nExtends the base input with `is_optional`, which is only valid on create.\nClients may send `is_optional=True` when a sibling already exists for the\nsame workorder+SIA (duplicate); the backend rejects it with a ValidationError\notherwise. Omitting the field triggers auto-detection. See Wrike 4462483155.", "properties": {"workorder": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "service_item_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Activity Id"}, "portal_service_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Portal Service Activity Id"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Internal"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "status_change_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Change By"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "ref_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ref Id"}, "preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Preset Id"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Optional"}}, "title": "WorkorderActivityCreateInput", "type": "object"}, "WorkorderBulkInput": {"additionalProperties": false, "description": "Payload for bulk-creating workorders.", "properties": {"workorders": {"items": {"$ref": "#/components/schemas/WorkorderInput"}, "title": "Workorders", "type": "array"}}, "required": ["workorders"], "title": "WorkorderBulkInput", "type": "object"}, "WorkorderCancelInput": {"additionalProperties": false, "description": "Payload for cancelling a workorder.", "properties": {"reason": {"title": "Reason", "type": "string"}}, "required": ["reason"], "title": "WorkorderCancelInput", "type": "object"}, "WorkorderActivityInput": {"additionalProperties": false, "description": "Payload for creating/updating workorder activities.", "properties": {"workorder": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "service_item_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Activity Id"}, "portal_service_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Portal Service Activity Id"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Internal"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "status_change_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Change By"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "ref_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ref Id"}, "preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Preset Id"}}, "title": "WorkorderActivityInput", "type": "object"}, "DelayBulkTeamUpdateItem": {"additionalProperties": false, "description": "Single delay team update item for bulk update.", "properties": {"delay_id": {"title": "Delay Id", "type": "integer"}, "team_resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Team Resources"}, "team_robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Team Robot Set Id"}}, "required": ["delay_id"], "title": "DelayBulkTeamUpdateItem", "type": "object"}, "WorkorderActivityBulkUpdateInput": {"additionalProperties": false, "description": "Payload for bulk-updating workorder activities (and optionally delay teams).", "properties": {"activities": {"default": [], "items": {"$ref": "#/components/schemas/WorkorderActivityBulkUpdateItem"}, "title": "Activities", "type": "array"}, "delays": {"default": [], "items": {"$ref": "#/components/schemas/DelayBulkTeamUpdateItem"}, "title": "Delays", "type": "array"}, "resource_change_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Change Comment"}, "preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Preset Id"}}, "title": "WorkorderActivityBulkUpdateInput", "type": "object"}, "WorkorderActivityBulkUpdateItem": {"additionalProperties": false, "description": "Single workorder activity patch item for bulk update.", "properties": {"workorder": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder"}, "service_item": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item"}, "service_item_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Item Activity Id"}, "portal_service_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Portal Service Activity Id"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Internal"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "status_change_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Change By"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "ref_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ref Id"}, "preset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Preset Id"}, "activity_id": {"title": "Activity Id", "type": "integer"}}, "required": ["activity_id"], "title": "WorkorderActivityBulkUpdateItem", "type": "object"}, "WorkorderActivityTimeEdit": {"additionalProperties": false, "description": "Audit row for a start/end datetime change on a workorder activity.", "properties": {"id": {"title": "Id", "type": "integer"}, "workorder_activity_id": {"title": "Workorder Activity Id", "type": "integer"}, "old_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Old Start Datetime"}, "new_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "New Start Datetime"}, "old_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Old End Datetime"}, "new_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "New End Datetime"}, "reason_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reason Code"}, "reason_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reason Name"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "source": {"title": "Source", "type": "string"}, "edited_at": {"format": "date-time", "title": "Edited At", "type": "string"}, "edited_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Edited By"}}, "required": ["id", "workorder_activity_id", "source", "edited_at"], "title": "WorkorderActivityTimeEdit", "type": "object"}, "WorkorderPlanQuery": {"additionalProperties": false, "description": "Query params for listing workorder plans.", "properties": {"workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}}, "title": "WorkorderPlanQuery", "type": "object"}, "WorkorderPlan": {"additionalProperties": false, "description": "Dispatch workorder plan.", "properties": {"plan_id": {"title": "Plan Id", "type": "integer"}, "workorder": {"title": "Workorder", "type": "integer"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}, "resource_type": {"title": "Resource Type", "type": "string"}, "planned_start_at": {"format": "date-time", "title": "Planned Start At", "type": "string"}, "planned_end_at": {"format": "date-time", "title": "Planned End At", "type": "string"}, "actual_start_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Actual Start At"}, "actual_end_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Actual End At"}, "status": {"title": "Status", "type": "string"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Created At"}, "updated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Updated At"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}}, "required": ["plan_id", "workorder", "resource_type", "planned_start_at", "planned_end_at", "status"], "title": "WorkorderPlan", "type": "object"}, "WorkorderPlanInput": {"additionalProperties": false, "description": "Payload for creating/updating workorder plans.", "properties": {"workorder": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}, "planned_start_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start At"}, "planned_end_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End At"}, "actual_start_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Actual Start At"}, "actual_end_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Actual End At"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "resources": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Resources"}}, "title": "WorkorderPlanInput", "type": "object"}, "WorkTimeLogQuery": {"additionalProperties": false, "description": "Query params for listing work time logs.", "properties": {"workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activity Id"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}}, "title": "WorkTimeLogQuery", "type": "object"}, "WorkTimeLog": {"additionalProperties": false, "description": "Dispatch work time log.", "properties": {"id": {"title": "Id", "type": "integer"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activity Id"}, "resource": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Min"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Timezone Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "activity_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Activity Start Datetime"}, "activity_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Activity End Datetime"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Custom Fields"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Created At"}, "created_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Created By"}, "corrected_entry_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Corrected Entry Id"}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "status_changed_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Changed By"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "pay_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pay Type"}, "approved_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Approved By"}, "approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Approved At"}, "approver_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approver Comment"}, "is_approved": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Approved"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}}, "required": ["id"], "title": "WorkTimeLog", "type": "object"}, "WorkTimeLogInput": {"additionalProperties": false, "description": "Payload for creating/updating work time logs.", "properties": {"workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activity Id"}, "resource": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Min"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "timezone_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Timezone Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "activity_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Activity Start Datetime"}, "activity_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Activity End Datetime"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Custom Fields"}, "created_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Created By"}, "corrected_entry_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Corrected Entry Id"}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "status_changed_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Status Changed By"}, "status_change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Change Reason"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "pay_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pay Type"}, "approved_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Approved By"}, "approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Approved At"}, "approver_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approver Comment"}, "is_approved": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Approved"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}}, "title": "WorkTimeLogInput", "type": "object"}, "WorkorderStatusChangeQuery": {"additionalProperties": false, "description": "Query params for listing workorder status changes.", "properties": {"workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}}, "title": "WorkorderStatusChangeQuery", "type": "object"}, "WorkorderStatusChange": {"additionalProperties": false, "description": "Dispatch workorder status change log.", "properties": {"id": {"title": "Id", "type": "integer"}, "workorder": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder"}, "old_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Old Status"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Change Reason"}, "change_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Change Note"}, "new_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "New Status"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Created At"}, "created_by": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Created By"}}, "required": ["id"], "title": "WorkorderStatusChange", "type": "object"}, "WorkorderActivityMetadataQuery": {"additionalProperties": false, "description": "Query params for listing workorder activity metadata.", "properties": {"workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}}, "title": "WorkorderActivityMetadataQuery", "type": "object"}, "WorkorderActivityMetadata": {"additionalProperties": false, "description": "Dispatch workorder activity metadata entry.", "properties": {"id": {"title": "Id", "type": "integer"}, "workorder_activity_id": {"title": "Workorder Activity Id", "type": "integer"}, "payload": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Payload"}}, "required": ["id", "workorder_activity_id"], "title": "WorkorderActivityMetadata", "type": "object"}, "WorkorderActivityMetadataInput": {"additionalProperties": false, "description": "Payload for creating workorder activity metadata.", "properties": {"workorder_activity_id": {"title": "Workorder Activity Id", "type": "integer"}, "payload": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Payload"}}, "required": ["workorder_activity_id"], "title": "WorkorderActivityMetadataInput", "type": "object"}, "WorkorderActivityMetadataPatchInput": {"additionalProperties": false, "description": "Payload for partially updating workorder activity metadata.", "properties": {"workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}, "payload": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "title": "Payload"}}, "title": "WorkorderActivityMetadataPatchInput", "type": "object"}, "BoardDataResponse": {"additionalProperties": false, "description": "Full response for the dispatching board.", "properties": {"resource_sets": {"items": {"$ref": "#/components/schemas/DispatchResourceSetResponse"}, "title": "Resource Sets", "type": "array"}, "workorders": {"items": {"$ref": "#/components/schemas/BoardWorkorderResponse"}, "title": "Workorders", "type": "array"}, "service_order_lines": {"items": {"$ref": "#/components/schemas/ServiceOrderLineGroup"}, "title": "Service Order Lines", "type": "array"}, "pending_scope_commitments": {"default": [], "items": {"$ref": "#/components/schemas/PendingScopeCommitmentResponse"}, "title": "Pending Scope Commitments", "type": "array"}, "missed_plans": {"default": [], "items": {"$ref": "#/components/schemas/MissedPlanResponse"}, "title": "Missed Plans", "type": "array"}, "earliest_planned_start": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Earliest Planned Start"}}, "required": ["resource_sets", "workorders", "service_order_lines"], "title": "BoardDataResponse", "type": "object"}, "BoardWorkorderActivityResponse": {"additionalProperties": false, "description": "A workorder activity surfaced on the board.\n\n``status`` / ``duration_minutes`` drive the card's activity strip (a\nproportional coloured segment per activity). ``custom_fields`` is the raw\nactivity custom-fields JSON and rides along for ADMIN workorders only \u2014 the\nboard popover extracts image attachments from it to show photo evidence.\n``start_datetime`` / ``end_datetime`` / ``resource_ids`` (FEAT-4909) let the\nfrontend group a multi-day workorder's activities by the day each one was\nactually worked, independent of the workorder's own planned window.", "properties": {"id": {"title": "Id", "type": "integer"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Minutes"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "object"}, {"type": "null"}], "title": "Custom Fields"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "resource_ids": {"default": [], "items": {"type": "integer"}, "title": "Resource Ids", "type": "array"}}, "required": ["id"], "title": "BoardWorkorderActivityResponse", "type": "object"}, "BoardWorkorderResponse": {"additionalProperties": false, "description": "A workorder for the dispatching board. ``actual_start_datetime`` is\nthe earliest non-cancelled activity's own start_datetime -- null until\nthe team actually starts work, distinct from the length carried by\n``estimated_duration_minutes``. Lets the board flag a planned-vs-actual\nstart discrepancy.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "planned_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start Datetime"}, "planned_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End Datetime"}, "actual_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Actual Start Datetime"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}, "service_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Order Number"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Id"}, "component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Position"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Quantity"}, "estimated_duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration Minutes"}, "assigned_resources": {"items": {"$ref": "#/components/schemas/WorkorderResourceResponse"}, "title": "Assigned Resources", "type": "array"}, "assignee_resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee Resource Id"}, "activities": {"default": [], "items": {"$ref": "#/components/schemas/BoardWorkorderActivityResponse"}, "title": "Activities", "type": "array"}, "is_logged_unplanned": {"default": false, "title": "Is Logged Unplanned", "type": "boolean"}}, "required": ["id", "assigned_resources"], "title": "BoardWorkorderResponse", "type": "object"}, "DispatchResourceSetResponse": {"additionalProperties": false, "description": "A project resource set with its members.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "project_location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Location Name"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "members": {"items": {"$ref": "#/components/schemas/ResourceSetMemberResponse"}, "title": "Members", "type": "array"}}, "required": ["id", "name", "members"], "title": "DispatchResourceSetResponse", "type": "object"}, "MissedPlanResponse": {"additionalProperties": false, "description": "A planned slot the board still shows on its original day -- a\nhistorical, non-interactive record. ``kind`` ``MISSED``: not completed by\nits planned day and returned to the backlog / cancelled. ``MOVED``: an\nin-progress workorder dragged to another day; ``source_workorder_id``\nlets the board say where it went.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_resource_set_id": {"title": "Project Resource Set Id", "type": "integer"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}, "label": {"title": "Label", "type": "string"}, "kind": {"title": "Kind", "type": "string"}, "source_workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Workorder Id"}}, "required": ["id", "project_resource_set_id", "planned_start_datetime", "planned_end_datetime", "label", "kind"], "title": "MissedPlanResponse", "type": "object"}, "PendingScopeCommitmentResponse": {"additionalProperties": false, "description": "One PENDING scope-dispatch commitment (DISP-3249) -- no SOL/Workorder yet.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "project_resource_set_id": {"title": "Project Resource Set Id", "type": "integer"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}}, "required": ["id", "service_id", "project_resource_set_id", "planned_start_datetime", "planned_end_datetime"], "title": "PendingScopeCommitmentResponse", "type": "object"}, "ResourceSetMemberResponse": {"additionalProperties": false, "description": "A member (resource) within a project resource set.", "properties": {"id": {"title": "Id", "type": "integer"}, "resource_id": {"title": "Resource Id", "type": "integer"}, "resource_name": {"title": "Resource Name", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Lead"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}}, "required": ["id", "resource_id", "resource_name"], "title": "ResourceSetMemberResponse", "type": "object"}, "ServiceOrderLineGroup": {"additionalProperties": false, "description": "A service order line with its child workorders.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "service_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Order Number"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Id"}, "component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Position"}, "workorder_ids": {"items": {"type": "integer"}, "title": "Workorder Ids", "type": "array"}}, "required": ["id", "workorder_ids"], "title": "ServiceOrderLineGroup", "type": "object"}, "WorkorderResourceResponse": {"additionalProperties": false, "description": "A resource assigned to a workorder.", "properties": {"resource_id": {"title": "Resource Id", "type": "integer"}, "resource_name": {"title": "Resource Name", "type": "string"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Lead"}}, "required": ["resource_id", "resource_name"], "title": "WorkorderResourceResponse", "type": "object"}, "BoardTurbineActivityGroupResponse": {"additionalProperties": false, "description": "One activity group (ServiceItem phase) on a turbine, with how many of\nits activities are completed vs the total (excludes CANCELLED activities).", "properties": {"name": {"title": "Name", "type": "string"}, "completed": {"title": "Completed", "type": "integer"}, "total": {"title": "Total", "type": "integer"}}, "required": ["name", "completed", "total"], "title": "BoardTurbineActivityGroupResponse", "type": "object"}, "BoardTurbineResponse": {"additionalProperties": false, "description": "A project-scope turbine (WTG) with its combined status.\n\n``status`` is a rollup of the turbine's non-cancelled workorders across the\nwhole project (any date), independent of the board's date window:\n``NO_WORK`` (no non-cancelled workorders), ``NOT_STARTED``, ``IN_PROGRESS``\n(any WO in progress), or ``COMPLETED`` (all WOs completed).\n\n``activity_groups`` breaks that rollup down per activity group (ServiceItem\nphase) so the board can show which groups are done: each entry carries the\ncompleted vs total non-cancelled ``WorkorderActivity`` count for that group\non this turbine, across the whole project.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"title": "Status", "type": "string"}, "activity_groups": {"default": [], "items": {"$ref": "#/components/schemas/BoardTurbineActivityGroupResponse"}, "title": "Activity Groups", "type": "array"}}, "required": ["id", "status"], "title": "BoardTurbineResponse", "type": "object"}, "BoardTurbinesResponse": {"additionalProperties": false, "properties": {"turbines": {"items": {"$ref": "#/components/schemas/BoardTurbineResponse"}, "title": "Turbines", "type": "array"}}, "required": ["turbines"], "title": "BoardTurbinesResponse", "type": "object"}, "BacklogAssignmentCounts": {"additionalProperties": false, "description": "Unassigned/assigned totals for the sidebar toggle (search scope only).", "properties": {"unassigned": {"title": "Unassigned", "type": "integer"}, "assigned": {"title": "Assigned", "type": "integer"}}, "required": ["unassigned", "assigned"], "title": "BacklogAssignmentCounts", "type": "object"}, "BacklogCounts": {"additionalProperties": false, "description": "Facet counts for the sidebar filter chips.\n\nEach facet is counted over the search + assignment scope BEFORE that\nfacet's own filter is applied (standard faceting), matching how the board\npreviously derived counts client-side.\n\n``logged_unplanned`` counts real work logged with no formal dispatch\n(DISP-4368) -- those workorders are already part of the unassigned scope\nabove, indistinguishable by status from any other untouched backlog row,\nso this facet is what makes them findable rather than buried among\nhundreds of genuinely untouched ones.", "properties": {"assignment": {"$ref": "#/components/schemas/BacklogAssignmentCounts"}, "statuses": {"items": {"$ref": "#/components/schemas/BacklogFacetCount"}, "title": "Statuses", "type": "array"}, "kinds": {"items": {"$ref": "#/components/schemas/BacklogFacetCount"}, "title": "Kinds", "type": "array"}, "services": {"items": {"$ref": "#/components/schemas/BacklogFacetCount"}, "title": "Services", "type": "array"}, "logged_unplanned": {"default": 0, "title": "Logged Unplanned", "type": "integer"}}, "required": ["assignment", "statuses", "kinds", "services"], "title": "BacklogCounts", "type": "object"}, "BacklogFacetCount": {"additionalProperties": false, "description": "One facet value with its count.\n\nList-of-objects rather than a value-keyed dict so the frontend's\ncamel/snake response transform can't mangle enum-ish keys like\n``NOT_STARTED``.", "properties": {"key": {"title": "Key", "type": "string"}, "count": {"title": "Count", "type": "integer"}}, "required": ["key", "count"], "title": "BacklogFacetCount", "type": "object"}, "BacklogPageResponse": {"additionalProperties": false, "description": "One page of the server-filtered sidebar work-order list.", "properties": {"items": {"items": {"$ref": "#/components/schemas/BoardWorkorderResponse"}, "title": "Items", "type": "array"}, "service_order_lines": {"items": {"$ref": "#/components/schemas/ServiceOrderLineGroup"}, "title": "Service Order Lines", "type": "array"}, "total_count": {"title": "Total Count", "type": "integer"}, "counts": {"$ref": "#/components/schemas/BacklogCounts"}}, "required": ["items", "service_order_lines", "total_count", "counts"], "title": "BacklogPageResponse", "type": "object"}, "BoardWeatherResponse": {"additionalProperties": false, "description": "Hourly weather for the dispatching day-Gantt.\n\n``available`` is False (with an empty ``hours`` list) when the project's\nprimary location has no coordinates or the forecast cache has no data for\nthat day \u2014 the board renders regardless.", "properties": {"available": {"title": "Available", "type": "boolean"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Name"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Longitude"}, "hours": {"items": {"$ref": "#/components/schemas/WeatherHourResponse"}, "title": "Hours", "type": "array"}}, "required": ["available", "hours"], "title": "BoardWeatherResponse", "type": "object"}, "WeatherHourResponse": {"additionalProperties": false, "description": "One hour of forecast weather for the project's location.\n\nUnits reflect what the Gust gateway returns (assumed m/s for wind,\ndegrees C for temperature/dew point, mm for precipitation, degrees for\ndirection) \u2014 see the units open point on Wrike 4506011329.", "properties": {"time": {"title": "Time", "type": "string"}, "temperature_c": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Temperature C"}, "humidity_pct": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Humidity Pct"}, "dew_point_c": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Dew Point C"}, "wind_speed_ms": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Wind Speed Ms"}, "wind_gust_ms": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Wind Gust Ms"}, "wind_direction_deg": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Wind Direction Deg"}, "precipitation_mm": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Precipitation Mm"}}, "required": ["time"], "title": "WeatherHourResponse", "type": "object"}, "ProjectCoverageDay": {"additionalProperties": false, "description": "One day's worth of resource-set coverage for a project.", "properties": {"date": {"title": "Date", "type": "string"}, "filled": {"title": "Filled", "type": "integer"}}, "required": ["date", "filled"], "title": "ProjectCoverageDay", "type": "object"}, "ProjectCoverageResponse": {"additionalProperties": false, "description": "Per-project resource-set coverage for a date window.\n\n`daily_filled` is a list of {date, filled} entries \u2014 list-of-objects rather\nthan a date-keyed dict so the axios camel/snake interceptor on the\nfrontend doesn't strip dashes from the date keys.\nCoverage % per day = filled / total_resource_sets.", "properties": {"project_id": {"title": "Project Id", "type": "integer"}, "total_resource_sets": {"title": "Total Resource Sets", "type": "integer"}, "daily_filled": {"items": {"$ref": "#/components/schemas/ProjectCoverageDay"}, "title": "Daily Filled", "type": "array"}}, "required": ["project_id", "total_resource_sets", "daily_filled"], "title": "ProjectCoverageResponse", "type": "object"}, "AdoptionCell": {"additionalProperties": false, "description": "One non-empty team-day. ``date`` is ISO ``YYYY-MM-DD`` in the project's\nlocal timezone; cells are a list, not a date-keyed dict, so the frontend\ncamel-case interceptor leaves the dates alone.", "properties": {"date": {"title": "Date", "type": "string"}, "workorders": {"items": {"$ref": "#/components/schemas/AdoptionWorkorderItem"}, "title": "Workorders", "type": "array"}, "pending": {"items": {"$ref": "#/components/schemas/AdoptionPendingItem"}, "title": "Pending", "type": "array"}, "missed": {"items": {"$ref": "#/components/schemas/AdoptionMissedItem"}, "title": "Missed", "type": "array"}, "logged_unplanned": {"items": {"$ref": "#/components/schemas/AdoptionLoggedItem"}, "title": "Logged Unplanned", "type": "array"}}, "required": ["date", "workorders", "pending", "missed", "logged_unplanned"], "title": "AdoptionCell", "type": "object"}, "AdoptionLoggedItem": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}}, "required": ["id", "name"], "title": "AdoptionLoggedItem", "type": "object"}, "AdoptionMissedItem": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "label": {"title": "Label", "type": "string"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}}, "required": ["id", "label"], "title": "AdoptionMissedItem", "type": "object"}, "AdoptionPendingItem": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "component_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Type"}}, "required": ["id"], "title": "AdoptionPendingItem", "type": "object"}, "AdoptionPerson": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "first_name": {"title": "First Name", "type": "string"}, "last_name": {"title": "Last Name", "type": "string"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Email"}}, "required": ["id", "first_name", "last_name"], "title": "AdoptionPerson", "type": "object"}, "AdoptionRow": {"additionalProperties": false, "properties": {"team_id": {"title": "Team Id", "type": "integer"}, "team_name": {"title": "Team Name", "type": "string"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "project_id": {"title": "Project Id", "type": "integer"}, "project_code": {"title": "Project Code", "type": "string"}, "project_manager": {"anyOf": [{"$ref": "#/components/schemas/AdoptionPerson"}, {"type": "null"}]}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Country"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Region"}, "supervisors": {"items": {"type": "string"}, "title": "Supervisors", "type": "array"}, "cells": {"items": {"$ref": "#/components/schemas/AdoptionCell"}, "title": "Cells", "type": "array"}}, "required": ["team_id", "team_name", "project_id", "project_code", "supervisors", "cells"], "title": "AdoptionRow", "type": "object"}, "AdoptionTableResponse": {"additionalProperties": false, "properties": {"since": {"title": "Since", "type": "string"}, "until": {"title": "Until", "type": "string"}, "days": {"items": {"type": "string"}, "title": "Days", "type": "array"}, "rows": {"items": {"$ref": "#/components/schemas/AdoptionRow"}, "title": "Rows", "type": "array"}}, "required": ["since", "until", "days", "rows"], "title": "AdoptionTableResponse", "type": "object"}, "AdoptionWorkorderItem": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "status": {"title": "Status", "type": "string"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}}, "required": ["id", "name", "status"], "title": "AdoptionWorkorderItem", "type": "object"}, "SupervisorOption": {"additionalProperties": false, "description": "A BTO supervisor and the core projects they supervise (DISP-2905).", "properties": {"name": {"title": "Name", "type": "string"}, "project_ids": {"items": {"type": "integer"}, "title": "Project Ids", "type": "array"}}, "required": ["name", "project_ids"], "title": "SupervisorOption", "type": "object"}, "AssignWorkorderPayload": {"additionalProperties": false, "description": "Payload for assigning a workorder to resources on a datetime.\n\n``assignee_resource_id`` optionally pins the workorder to a single\nindividual within the set (ADMIN WOs only); recorded as a\n``WorkorderResource`` row and must be one of ``resource_ids``.", "properties": {"workorder_id": {"title": "Workorder Id", "type": "integer"}, "resource_ids": {"items": {"type": "integer"}, "title": "Resource Ids", "type": "array"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End Datetime"}, "assignee_resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Assignee Resource Id"}}, "required": ["workorder_id", "resource_ids", "planned_start_datetime"], "title": "AssignWorkorderPayload", "type": "object"}, "BulkAssignWorkordersPayload": {"additionalProperties": false, "description": "Payload for bulk-assigning workorders to resources.", "properties": {"assignments": {"items": {"$ref": "#/components/schemas/AssignWorkorderPayload"}, "title": "Assignments", "type": "array"}}, "required": ["assignments"], "title": "BulkAssignWorkordersPayload", "type": "object"}, "UnassignWorkorderPayload": {"additionalProperties": false, "description": "Payload for unassigning a workorder.", "properties": {"workorder_id": {"title": "Workorder Id", "type": "integer"}}, "required": ["workorder_id"], "title": "UnassignWorkorderPayload", "type": "object"}, "UpdateAdminWorkorderResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}}, "required": ["id", "name", "planned_start_datetime", "planned_end_datetime"], "title": "UpdateAdminWorkorderResponse", "type": "object"}, "UpdateAdminWorkorderPayload": {"additionalProperties": false, "description": "Payload for editing an existing ADMIN workorder's name/duration\n(DISP-2892).\n\n``duration_minutes`` only moves ``planned_end_datetime`` --\n``planned_start_datetime`` (and therefore the board's lane placement)\nnever changes from an edit; that's what \"Move to next day\" (DISP-3391)\nis for. Assignee/activities are edited through their own endpoints.", "properties": {"name": {"title": "Name", "type": "string"}, "duration_minutes": {"minimum": 5, "title": "Duration Minutes", "type": "integer"}}, "required": ["name", "duration_minutes"], "title": "UpdateAdminWorkorderPayload", "type": "object"}, "SetWorkorderTurbinePayload": {"additionalProperties": false, "description": "Payload for binding a turbine to a scope-dispatched workorder.", "properties": {"turbine_id": {"title": "Turbine Id", "type": "integer"}}, "required": ["turbine_id"], "title": "SetWorkorderTurbinePayload", "type": "object"}, "CreateAdminWorkorderResponse": {"additionalProperties": false, "description": "Result of creating an ADMIN workorder.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "assignee_resource_id": {"title": "Assignee Resource Id", "type": "integer"}}, "required": ["id", "name", "assignee_resource_id"], "title": "CreateAdminWorkorderResponse", "type": "object"}, "AdminActivityInput": {"additionalProperties": false, "description": "One activity, shared by \"create a new ADMIN workorder\" (DISP-2379)\nand \"add an activity to an already-created one\" (``add_workorder_activity``\nbelow).\n\n``estimated_duration_minutes`` stays optional here -- adding to an existing\nWO has never required one -- but if given it must be a real, positive\nnumber, never the old silent-zero default. Workorder *creation* additionally\nrequires every activity to carry one; see\n``CreateAdminWorkorderPayload.validate_payload``.\n\n``image_required`` (FEAT-2554) mirrors the ``custom_fields`` shape the\n\"Replace Cleaning Cloth\" field activity already uses to require a photo\nbefore AeroTask lets the activity complete (see migration\n0047_add_replace_cleaning_cloth_activities) -- reused verbatim here rather\nthan inventing a second mechanism for the same thing.", "properties": {"description": {"title": "Description", "type": "string"}, "estimated_duration_minutes": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Estimated Duration Minutes"}, "image_required": {"default": false, "title": "Image Required", "type": "boolean"}}, "required": ["description"], "title": "AdminActivityInput", "type": "object"}, "CreateAdminWorkorderPayload": {"additionalProperties": false, "description": "Payload for creating an ADMIN workorder pinned to a single technician.\n\nAn admin workorder is standalone work (no service order line) scoped to the\ncurrently-open project: it inherits the project's ``requesting_customer`` so\nthe row is visible under the customer-scoped RLS policy and returned by the\nproject ``board-data`` query. ``assignee_resource_id`` pins the WO to one\nindividual so the board routes it into that member's person lane; the\nresource must belong to an active project resource set of this project.\n\n``activities`` requires at least one entry -- AeroTask's start/finish/\nupdate flow acts on WorkorderActivity rows, not bare workorders, so an\nADMIN WO with none is inert on mobile (DISP-2379). FEAT-2554 dropped the\nfree-text whole-WO ``description`` in favour of the Activities section\n(which now always carries real, timed activities) and caps their combined\nduration at the workorder's own -- both enforced below.\n\n``auto_carry_over`` is opt-in (DISP-3391): while the workorder is\nincomplete, the hourly carry-over task keeps shifting its planned window\nonto the site's current day.", "properties": {"name": {"title": "Name", "type": "string"}, "assignee_resource_id": {"title": "Assignee Resource Id", "type": "integer"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}, "activities": {"items": {"$ref": "#/components/schemas/AdminActivityInput"}, "title": "Activities", "type": "array"}, "auto_carry_over": {"default": false, "title": "Auto Carry Over", "type": "boolean"}}, "required": ["name", "assignee_resource_id", "planned_start_datetime", "planned_end_datetime", "activities"], "title": "CreateAdminWorkorderPayload", "type": "object"}, "AddWorkorderActivityResponse": {"additionalProperties": false, "description": "Result of adding an activity to an existing ADMIN workorder.", "properties": {"id": {"title": "Id", "type": "integer"}, "description": {"title": "Description", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "required": ["id", "description"], "title": "AddWorkorderActivityResponse", "type": "object"}, "UpdateWorkorderActivityResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "description": {"title": "Description", "type": "string"}, "estimated_duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration Minutes"}, "image_required": {"title": "Image Required", "type": "boolean"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "required": ["id", "description", "estimated_duration_minutes", "image_required"], "title": "UpdateWorkorderActivityResponse", "type": "object"}, "UpdateWorkorderActivityPayload": {"additionalProperties": false, "description": "Payload for editing one activity on an existing ADMIN workorder\n(DISP-2892) -- name, duration, and the image-required toggle.", "properties": {"description": {"title": "Description", "type": "string"}, "estimated_duration_minutes": {"anyOf": [{"minimum": 1, "type": "integer"}, {"type": "null"}], "title": "Estimated Duration Minutes"}, "image_required": {"default": false, "title": "Image Required", "type": "boolean"}}, "required": ["description"], "title": "UpdateWorkorderActivityPayload", "type": "object"}, "ScopeGroupResponse": {"additionalProperties": false, "description": "One scope bucket. `remaining` = total minus pending commitments and\nitems already claimed by an actively dispatched workorder.\n\n``default_kpi_minutes`` is the benchmark minutes per unit; it prefills\n(and stays editable as) the dispatcher's per-unit duration when planning\nby scope. This project's own ``ProjectServiceKpi`` override, when set,\nwins over this flat value -- see ``ProjectServiceKpiManager``.", "properties": {"service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "total": {"title": "Total", "type": "integer"}, "remaining": {"title": "Remaining", "type": "integer"}, "unit": {"title": "Unit", "type": "string"}, "default_kpi_minutes": {"title": "Default Kpi Minutes", "type": "integer"}}, "required": ["service_id", "service_code", "total", "remaining", "unit", "default_kpi_minutes"], "title": "ScopeGroupResponse", "type": "object"}, "CreateScopeWorkorderResponse": {"additionalProperties": false, "description": "`quantity` independent pending commitments, window split evenly.", "properties": {"commitments": {"items": {"$ref": "#/components/schemas/ScopeDispatchCommitmentItem"}, "title": "Commitments", "type": "array"}, "quantity": {"title": "Quantity", "type": "integer"}, "unit": {"title": "Unit", "type": "string"}}, "required": ["commitments", "quantity", "unit"], "title": "CreateScopeWorkorderResponse", "type": "object"}, "ScopeDispatchCommitmentItem": {"additionalProperties": false, "description": "One pending commitment row.", "properties": {"id": {"title": "Id", "type": "integer"}, "status": {"title": "Status", "type": "string"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}}, "required": ["id", "status", "planned_start_datetime", "planned_end_datetime"], "title": "ScopeDispatchCommitmentItem", "type": "object"}, "CreateScopeWorkorderPayload": {"additionalProperties": false, "description": "Payload for dispatching a team against a scope bucket. ``component_type_id``\nidentifies which bucket's ProjectScopeItems this dispatch targets when a\nservice spans more than one component type (e.g. both blade-level and\nwhole-turbine scope) -- must match exactly what ``list_scope_groups``\nreported for the chosen bucket, including ``None``. Buckets are not\nsite-scoped: a single commitment can be resolved against a turbine at\nany site offering this service.", "properties": {"service_id": {"title": "Service Id", "type": "integer"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Type Id"}, "resource_set_id": {"title": "Resource Set Id", "type": "integer"}, "planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}, "quantity": {"default": 1, "title": "Quantity", "type": "integer"}}, "required": ["service_id", "resource_set_id", "planned_start_datetime", "planned_end_datetime"], "title": "CreateScopeWorkorderPayload", "type": "object"}, "ScopeCommitmentTurbineOption": {"additionalProperties": false, "description": "A turbine this commitment can actually resolve to.", "properties": {"turbine_id": {"title": "Turbine Id", "type": "integer"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}}, "required": ["turbine_id"], "title": "ScopeCommitmentTurbineOption", "type": "object"}, "ResolveScopeCommitmentPayload": {"additionalProperties": false, "description": "`turbine_component_id` disambiguates component-level buckets.", "properties": {"turbine_id": {"title": "Turbine Id", "type": "integer"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}}, "required": ["turbine_id"], "title": "ResolveScopeCommitmentPayload", "type": "object"}, "RescheduleScopeCommitmentPayload": {"additionalProperties": false, "description": "Payload for rescheduling (and optionally re-teaming) a still-pending\nscope-dispatch commitment.", "properties": {"planned_start_datetime": {"format": "date-time", "title": "Planned Start Datetime", "type": "string"}, "planned_end_datetime": {"format": "date-time", "title": "Planned End Datetime", "type": "string"}, "resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Set Id"}}, "required": ["planned_start_datetime", "planned_end_datetime"], "title": "RescheduleScopeCommitmentPayload", "type": "object"}, "DayCommentaryResponse": {"additionalProperties": false, "description": "One day-commentary entry.", "properties": {"id": {"title": "Id", "type": "integer"}, "date": {"format": "date", "title": "Date", "type": "string"}, "category": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category"}, "text": {"title": "Text", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}}, "required": ["id", "date", "text", "created_at"], "title": "DayCommentaryResponse", "type": "object"}, "DayCommentaryPayload": {"additionalProperties": false, "description": "Payload for a dispatcher's free-form note about one day (DISP-2285).", "properties": {"date": {"format": "date", "title": "Date", "type": "string"}, "category": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category"}, "text": {"title": "Text", "type": "string"}}, "required": ["date", "text"], "title": "DayCommentaryPayload", "type": "object"}, "ServiceKpiResponse": {"additionalProperties": false, "description": "One service's KPI (benchmark duration) setting for a project (DISP-2988).\n\n`kpi_minutes` is what the dispatching board actually uses for this\nservice on this project today -- the project override when\n`has_override` is true, else the flat `Service.default_kpi_minutes`.", "properties": {"service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "kpi_minutes": {"title": "Kpi Minutes", "type": "integer"}, "default_kpi_minutes": {"title": "Default Kpi Minutes", "type": "integer"}, "has_override": {"title": "Has Override", "type": "boolean"}}, "required": ["service_id", "service_code", "kpi_minutes", "default_kpi_minutes", "has_override"], "title": "ServiceKpiResponse", "type": "object"}, "SetServiceKpiPayload": {"additionalProperties": false, "description": "Payload to set a project's KPI override for one service (DISP-2988).", "properties": {"kpi_minutes": {"title": "Kpi Minutes", "type": "integer"}}, "required": ["kpi_minutes"], "title": "SetServiceKpiPayload", "type": "object"}, "TeamMessageAttachmentResponse": {"additionalProperties": false, "description": "One image attached to a team message.", "properties": {"id": {"title": "Id", "type": "integer"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}}, "required": ["id"], "title": "TeamMessageAttachmentResponse", "type": "object"}, "TeamMessageResponse": {"additionalProperties": false, "description": "A team message with its current (possibly still-pending) reaction.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_resource_set_id": {"title": "Project Resource Set Id", "type": "integer"}, "date": {"format": "date", "title": "Date", "type": "string"}, "text": {"title": "Text", "type": "string"}, "reaction": {"title": "Reaction", "type": "string"}, "reaction_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reaction Comment"}, "reacted_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Reacted At"}, "sent_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sent By"}, "sent_at": {"format": "date-time", "title": "Sent At", "type": "string"}, "attachments": {"items": {"$ref": "#/components/schemas/TeamMessageAttachmentResponse"}, "title": "Attachments", "type": "array"}}, "required": ["id", "project_resource_set_id", "date", "text", "reaction", "sent_at", "attachments"], "title": "TeamMessageResponse", "type": "object"}, "CreateTeamMessagePayload": {"additionalProperties": false, "description": "Payload for a dispatcher message to a team, dated today or later\n(DISP-2288). Images are pre-uploaded via ``POST /core/v1/files/`` (bare);\ntheir ids are passed here to be linked in the same transaction.", "properties": {"project_resource_set_id": {"title": "Project Resource Set Id", "type": "integer"}, "date": {"format": "date", "title": "Date", "type": "string"}, "text": {"title": "Text", "type": "string"}, "image_file_ids": {"items": {"type": "integer"}, "title": "Image File Ids", "type": "array"}}, "required": ["project_resource_set_id", "date", "text"], "title": "CreateTeamMessagePayload", "type": "object"}, "PlatformClient": {"additionalProperties": false, "description": "Definition of a client in the platform.", "properties": {"id": {"description": "platform id of particular client", "title": "Id", "type": "integer"}, "name": {"description": "Name of the client as in platform", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "PlatformClient", "type": "object"}, "PlatformClients": {"additionalProperties": false, "description": "Definition of a list of clients in the platform.", "properties": {"items": {"description": "List of clients in the platform", "items": {"$ref": "#/components/schemas/PlatformClient"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "PlatformClients", "type": "object"}, "DailyReport": {"additionalProperties": false, "description": "Schema for daily report from Platform.", "properties": {"report_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Report Id"}, "report_type": {"title": "Report Type", "type": "string"}, "report_token": {"title": "Report Token", "type": "string"}, "url": {"title": "Url", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "report_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Report Date"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "archived": {"title": "Archived", "type": "boolean"}, "winch_sets": {"default": [], "items": {"$ref": "#/components/schemas/DailyReportWinchSet"}, "title": "Winch Sets", "type": "array"}, "services": {"default": [], "items": {"$ref": "#/components/schemas/DailyReportService"}, "title": "Services", "type": "array"}}, "required": ["report_type", "report_token", "url", "created_at", "updated_at", "archived"], "title": "DailyReport", "type": "object"}, "DailyReportDay": {"additionalProperties": false, "description": "Schema for a day's daily reports from Platform.", "properties": {"date": {"format": "date", "title": "Date", "type": "string"}, "reports": {"default": [], "items": {"$ref": "#/components/schemas/DailyReport"}, "title": "Reports", "type": "array"}, "missing_reports": {"default": [], "items": {"$ref": "#/components/schemas/MissingReport"}, "title": "Missing Reports", "type": "array"}}, "required": ["date"], "title": "DailyReportDay", "type": "object"}, "DailyReportService": {"additionalProperties": false, "description": "Schema for service in daily report.", "properties": {"service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "service_type_code": {"title": "Service Type Code", "type": "string"}}, "required": ["service_id", "service_code", "service_type_code"], "title": "DailyReportService", "type": "object"}, "DailyReportWinchSet": {"additionalProperties": false, "description": "Schema for winch set in daily report.", "properties": {"winch_set_id": {"title": "Winch Set Id", "type": "integer"}, "winch_set_name": {"title": "Winch Set Name", "type": "string"}}, "required": ["winch_set_id", "winch_set_name"], "title": "DailyReportWinchSet", "type": "object"}, "DailyReportsResponse": {"additionalProperties": false, "description": "Schema for daily reports response.", "properties": {"days": {"default": [], "items": {"$ref": "#/components/schemas/DailyReportDay"}, "title": "Days", "type": "array"}}, "title": "DailyReportsResponse", "type": "object"}, "MissingReport": {"additionalProperties": false, "description": "Schema for missing daily report from Platform.", "properties": {"winch_set_id": {"title": "Winch Set Id", "type": "integer"}, "winch_set_name": {"title": "Winch Set Name", "type": "string"}, "status": {"default": "MISSING", "title": "Status", "type": "string"}, "workorders": {"default": [], "items": {"$ref": "#/components/schemas/MissingReportWorkorder"}, "title": "Workorders", "type": "array"}}, "required": ["winch_set_id", "winch_set_name"], "title": "MissingReport", "type": "object"}, "MissingReportWorkorder": {"additionalProperties": false, "description": "Schema for workorder in missing report.", "properties": {"workorder_id": {"title": "Workorder Id", "type": "integer"}, "workorder_name": {"title": "Workorder Name", "type": "string"}}, "required": ["workorder_id", "workorder_name"], "title": "MissingReportWorkorder", "type": "object"}, "ProjectListQuery": {"additionalProperties": false, "description": "Query parameters for project list endpoint.", "properties": {"code": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "not_null", "description": "Filter by code: 'all' to show all projects, 'not_null' to show only projects with code", "title": "Code"}, "hasBuilderId": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "default": true, "title": "Hasbuilderid"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search projects by code", "title": "Search"}, "filter[name]": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Exact project title filter", "title": "Filter[Name]"}, "filter[name][like]": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Case-insensitive partial project title filter", "title": "Filter[Name][Like]"}, "page": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1, "title": "Page"}, "page_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1000, "title": "Page Size"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "title": "ProjectListQuery", "type": "object"}, "Client": {"additionalProperties": false, "description": "Schema for client.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Client name.", "title": "Name"}}, "title": "Client", "type": "object"}, "Country": {"additionalProperties": false, "description": "Schema for Country.", "properties": {"code": {"description": "Country code in alpha-2.", "title": "Code", "type": "string"}, "name": {"description": "Human readable country name.", "title": "Name", "type": "string"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Custom region name a country belongs to.", "title": "Region"}}, "required": ["code", "name"], "title": "Country", "type": "object"}, "ProjectList": {"additionalProperties": false, "description": "Schema for project list.", "properties": {"origin_id": {"description": "Project origin identifier, e.g. pipedrive id.", "title": "Origin Id", "type": "string"}, "id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project unique identifier in project builder.", "title": "Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project unique code shared with Pipedrive.", "title": "Code"}, "title": {"description": "Project title.", "title": "Title", "type": "string"}, "client": {"anyOf": [{"$ref": "#/components/schemas/Client"}, {"type": "null"}], "description": "Client information."}, "country": {"anyOf": [{"$ref": "#/components/schemas/Country"}, {"type": "null"}], "description": "Country information."}, "timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Timezone"}, "windparks": {"items": {"$ref": "#/components/schemas/WindparkProjectList"}, "title": "Windparks", "type": "array"}, "status": {"title": "Status", "type": "string"}, "user_status": {"anyOf": [{"$ref": "#/components/schemas/UserStatus"}, {"type": "null"}]}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "services": {"default": [], "items": {"type": "string"}, "title": "Services", "type": "array"}, "sales_executives": {"default": [], "items": {"type": "string"}, "title": "Sales Executives", "type": "array"}, "potential_start_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Potential Start Date"}}, "required": ["origin_id", "title", "windparks", "status", "created_at", "updated_at"], "title": "ProjectList", "type": "object"}, "UserStatus": {"description": "Enum for user-defined project statuses.", "enum": ["Cancelled", "Completed", "Customer PJ in progress", "Customer PJ in review", "Customer PJ done", "Customer PJ rejected"], "title": "UserStatus", "type": "string"}, "WindparkProjectList": {"additionalProperties": false, "description": "Schema for windpark in project list.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Windpark identifier in project builder, may not exist.", "title": "Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Windpark name.", "title": "Name"}}, "title": "WindparkProjectList", "type": "object"}, "Project": {"additionalProperties": false, "description": "Schema for project.", "properties": {"id": {"description": "Project unique identifier.", "title": "Id", "type": "string"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project unique code shared with Pipedrive.", "title": "Code"}, "client": {"anyOf": [{"$ref": "#/components/schemas/Client"}, {"type": "null"}], "description": "Client information."}, "country": {"anyOf": [{"$ref": "#/components/schemas/Country"}, {"type": "null"}], "description": "Country information."}, "timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IANA Timezone name.", "title": "Timezone"}, "sites": {"default": [], "description": "List of project sites with location information.", "items": {"$ref": "#/components/schemas/ProjectSiteSimple"}, "title": "Sites", "type": "array"}, "status": {"description": "Project current status.", "title": "Status", "type": "string"}, "user_status": {"anyOf": [{"$ref": "#/components/schemas/UserStatus"}, {"type": "null"}]}, "offer_status": {"anyOf": [{"$ref": "#/components/schemas/ProjectOfferStatus"}, {"type": "null"}]}, "offer_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "CO version number, only returned when offer_status is 'Approved'", "title": "Offer Version"}, "created_at": {"description": "Project creation timestamp.", "format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"description": "Project last update timestamp.", "format": "date-time", "title": "Updated At", "type": "string"}, "origin_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project origin identifier, e.g.pipedrive id.", "title": "Origin Id"}, "sales_executives": {"default": [], "items": {"type": "string"}, "title": "Sales Executives", "type": "array"}, "services": {"default": [], "items": {"type": "string"}, "title": "Services", "type": "array"}, "related_projects": {"default": [], "description": "Other projects that share client and site with this project.", "items": {"type": "string"}, "title": "Related Projects", "type": "array"}, "platform_sent": {"default": false, "description": "Whether the project was sent to the platform.", "title": "Platform Sent", "type": "boolean"}, "rfi_completion": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "RFI overall completion percentage (0-100)", "title": "Rfi Completion"}, "prejob_completion": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pre-job overall completion percentage (0-100)", "title": "Prejob Completion"}}, "required": ["id", "status", "created_at", "updated_at", "origin_id"], "title": "Project", "type": "object"}, "ProjectOfferStatus": {"description": "Project level Offer status.", "enum": ["Draft", "Pending", "Approved", "Rejected", "Changed"], "title": "ProjectOfferStatus", "type": "string"}, "ProjectSiteSimple": {"additionalProperties": false, "description": "Schema for project site information.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site name", "title": "Name"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Site latitude", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Site longitude", "title": "Longitude"}}, "title": "ProjectSiteSimple", "type": "object"}, "ProjectPOST": {"additionalProperties": false, "description": "Schema for project creation.", "properties": {"origin_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project origin identifier (Pipedrive deal ID). Required for Pipedrive path.", "title": "Origin Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Core project code. Required when origin_id is not provided (platform path).", "title": "Code"}}, "title": "ProjectPOST", "type": "object"}, "ProjectServiceCode": {"additionalProperties": false, "description": "Schema for a project service code entry with manufacturer/model context.", "properties": {"full_code": {"description": "Full service code like 'IIN-ONS'", "title": "Full Code", "type": "string"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full service name like 'Internal Inspection - Onshore'", "title": "Full Name"}, "group_id": {"description": "Asset group ID this service belongs to", "title": "Group Id", "type": "integer"}, "manufacturer": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Main manufacturer for the unit type", "title": "Manufacturer"}, "model": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Main model for the unit type", "title": "Model"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Site ID this service is associated with", "title": "Site Id"}, "site_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site name this service is associated with", "title": "Site Name"}}, "required": ["full_code", "group_id"], "title": "ProjectServiceCode", "type": "object"}, "ProjectPassword": {"additionalProperties": false, "description": "Schema for project password.", "properties": {"password": {"description": "Project password", "title": "Password", "type": "string"}}, "required": ["password"], "title": "ProjectPassword", "type": "object"}, "ProjectEmailResponse": {"additionalProperties": false, "description": "Schema for project email response.", "properties": {"success": {"description": "Whether the email was sent successfully", "title": "Success", "type": "boolean"}, "message": {"description": "Response message", "title": "Message", "type": "string"}}, "required": ["success", "message"], "title": "ProjectEmailResponse", "type": "object"}, "ProjectEmailRequest": {"additionalProperties": false, "description": "Schema for project email request.", "properties": {"recipient_email": {"description": "Email address of the recipient", "format": "email", "title": "Recipient Email", "type": "string"}}, "required": ["recipient_email"], "title": "ProjectEmailRequest", "type": "object"}, "UserStatusPayload": {"additionalProperties": false, "description": "Schema for updating user_status.", "properties": {"user_status": {"$ref": "#/components/schemas/UserStatus", "description": "The new user status for the project."}, "reason": {"anyOf": [{"maxLength": 1000, "type": "string"}, {"type": "null"}], "description": "Required when user_status is Cancelled; stored as the status-history note.", "title": "Reason"}}, "required": ["user_status"], "title": "UserStatusPayload", "type": "object"}, "Customer": {"additionalProperties": false, "description": "Schema for customer.", "properties": {"id": {"description": "NetSuite ID for customer", "title": "Id", "type": "integer"}, "alt_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Alterative (more human-friendly) NetSuite, e.g. `CUST0008`", "title": "Alt Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name", "title": "Name"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency", "title": "Currency"}, "business_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Business ID", "title": "Business Id"}, "address_text": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full address in single text/string", "title": "Address Text"}}, "required": ["id"], "title": "Customer", "type": "object"}, "RelatedProjectsQuery": {"additionalProperties": false, "description": "Query parameters for related projects endpoint.", "properties": {"match": {"anyOf": [{"maximum": 100, "minimum": 1, "type": "integer"}, {"type": "null"}], "default": 60, "description": "Minimum fuzzy match score percentage (1-100, default 60)", "title": "Match"}}, "title": "RelatedProjectsQuery", "type": "object"}, "RelatedProject": {"additionalProperties": false, "description": "Schema for related project with code, id, client name and match score.", "properties": {"id": {"description": "Project unique identifier.", "title": "Id", "type": "string"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project unique code shared with Pipedrive.", "title": "Code"}, "client_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Client/company name.", "title": "Client Name"}, "match_score": {"description": "Fuzzy match score as percentage (0-100).", "title": "Match Score", "type": "number"}}, "required": ["id", "match_score"], "title": "RelatedProject", "type": "object"}, "RelatedProjectsResponse": {"additionalProperties": false, "description": "Schema for related projects response.", "properties": {"related_projects": {"default": [], "description": "List of related projects with their code and id.", "items": {"$ref": "#/components/schemas/RelatedProject"}, "title": "Related Projects", "type": "array"}}, "title": "RelatedProjectsResponse", "type": "object"}, "ProjectLead": {"additionalProperties": false, "description": "Schema for project lead.", "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "email": {"anyOf": [{"format": "email", "type": "string"}, {"type": "null"}], "title": "Email"}, "phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Phone"}, "role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Role"}}, "title": "ProjectLead", "type": "object"}, "ProjectRFIGeneralEdit": {"additionalProperties": false, "description": "Schema for project general creation.", "properties": {"project_leads": {"anyOf": [{"items": {"$ref": "#/components/schemas/ProjectLead"}, "type": "array"}, {"type": "null"}], "title": "Project Leads"}, "company_legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Legal Name"}, "company_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Address"}, "company_vat_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Vat Id"}, "company_reg_no": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Reg No"}, "platform_client_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Platform Client Id"}}, "title": "ProjectRFIGeneralEdit", "type": "object"}, "ProjectRFIGeneral": {"additionalProperties": false, "description": "Schema for project general.", "properties": {"project_leads": {"anyOf": [{"items": {"$ref": "#/components/schemas/ProjectLead"}, "type": "array"}, {"type": "null"}], "title": "Project Leads"}, "company_legal_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Legal Name"}, "company_address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Address"}, "company_vat_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Vat Id"}, "company_reg_no": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Reg No"}, "company_netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Company Netsuite Id"}, "platform_client_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Platform Client Id"}}, "title": "ProjectRFIGeneral", "type": "object"}, "InvoicingMethod": {"description": "Invoicing method definitions.", "enum": ["email", "portal"], "title": "InvoicingMethod", "type": "string"}, "ProjectBilling": {"additionalProperties": false, "description": "Schema for project billing.\n\nCurrency is mandatory and defaults to EUR if not provided.\nAll other fields are optional.", "properties": {"subsidiary_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite id of Aerones billing entity for this project", "title": "Subsidiary Id"}, "subsidiary_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of Aerones billing entity for this project", "title": "Subsidiary Name"}, "billing_lead_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the billing lead", "title": "Billing Lead Name"}, "billing_lead_email": {"anyOf": [{"format": "email", "type": "string"}, {"type": "null"}], "description": "Email of the billing lead", "title": "Billing Lead Email"}, "billing_lead_phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number of the billing lead", "title": "Billing Lead Phone"}, "legal_entity": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the company that will receive the invoice", "title": "Legal Entity"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "address_state": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address State"}, "payment_terms": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Payment Terms"}, "payment_terms_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comment for payment terms", "title": "Payment Terms Comment"}, "purchase_order_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Purchase Order Required"}, "purchase_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Purchase Order Number"}, "purchase_order_value": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Purchase Order Value"}, "currency": {"default": "EUR", "description": "Currency code (e.g. EUR, USD, CAD, AUD)", "title": "Currency", "type": "string"}, "invoicing_method": {"anyOf": [{"$ref": "#/components/schemas/InvoicingMethod"}, {"type": "null"}]}, "invoicing_instructions": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional instructions for invoicing", "title": "Invoicing Instructions"}, "invoicing_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address to send invoices to", "title": "Invoicing Email"}, "invoice_frequency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Frequency of invoicing", "title": "Invoice Frequency"}}, "title": "ProjectBilling", "type": "object"}, "PaymentTerms": {"description": "Payment terms definitions.", "enum": ["30", "45", "60", "90"], "title": "PaymentTerms", "type": "string"}, "ProjectBillingEdit": {"additionalProperties": false, "description": "Schema for project billing update.", "properties": {"subsidiary_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite id of Aerones billing entity for this project", "title": "Subsidiary Id"}, "subsidiary_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of Aerones billing entity for this project", "title": "Subsidiary Name"}, "billing_lead_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the billing lead", "title": "Billing Lead Name"}, "billing_lead_email": {"anyOf": [{"format": "email", "type": "string"}, {"type": "null"}], "description": "Email of the billing lead", "title": "Billing Lead Email"}, "billing_lead_phone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Phone number of the billing lead", "title": "Billing Lead Phone"}, "legal_entity": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the company that will receive the invoice", "title": "Legal Entity"}, "address": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address"}, "address_state": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Address State"}, "payment_terms": {"anyOf": [{"$ref": "#/components/schemas/PaymentTerms"}, {"type": "null"}]}, "payment_terms_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comment for payment terms", "title": "Payment Terms Comment"}, "purchase_order_required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Purchase Order Required"}, "purchase_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Purchase Order Number"}, "purchase_order_value": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Purchase Order Value"}, "currency": {"default": "EUR", "description": "Currency code (e.g. EUR, USD, CAD, AUD)", "title": "Currency", "type": "string"}, "invoicing_method": {"anyOf": [{"$ref": "#/components/schemas/InvoicingMethod"}, {"type": "null"}]}, "invoicing_instructions": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional instructions for invoicing", "title": "Invoicing Instructions"}, "invoicing_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email address to send invoices to", "title": "Invoicing Email"}, "invoice_frequency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Frequency of invoicing", "title": "Invoice Frequency"}}, "title": "ProjectBillingEdit", "type": "object"}, "ProjectPrefillQuery": {"additionalProperties": false, "description": "Query parameters for project prefill endpoints.", "properties": {"reference": {"description": "Project id that will be used for prefilling data", "title": "Reference", "type": "string"}}, "required": ["reference"], "title": "ProjectPrefillQuery", "type": "object"}, "Prefill_EmailStr_": {"additionalProperties": false, "properties": {"value": {"format": "email", "title": "Value", "type": "string"}, "prefilled": {"default": true, "description": "Whether the value is prefilled.", "title": "Prefilled", "type": "boolean"}}, "required": ["value"], "title": "Prefill[EmailStr]", "type": "object"}, "Prefill_InvoicingMethod_": {"additionalProperties": false, "properties": {"value": {"$ref": "#/components/schemas/InvoicingMethod"}, "prefilled": {"default": true, "description": "Whether the value is prefilled.", "title": "Prefilled", "type": "boolean"}}, "required": ["value"], "title": "Prefill[InvoicingMethod]", "type": "object"}, "Prefill_bool_": {"additionalProperties": false, "properties": {"value": {"title": "Value", "type": "boolean"}, "prefilled": {"default": true, "description": "Whether the value is prefilled.", "title": "Prefilled", "type": "boolean"}}, "required": ["value"], "title": "Prefill[bool]", "type": "object"}, "Prefill_float_": {"additionalProperties": false, "properties": {"value": {"title": "Value", "type": "number"}, "prefilled": {"default": true, "description": "Whether the value is prefilled.", "title": "Prefilled", "type": "boolean"}}, "required": ["value"], "title": "Prefill[float]", "type": "object"}, "Prefill_str_": {"additionalProperties": false, "properties": {"value": {"title": "Value", "type": "string"}, "prefilled": {"default": true, "description": "Whether the value is prefilled.", "title": "Prefilled", "type": "boolean"}}, "required": ["value"], "title": "Prefill[str]", "type": "object"}, "ProjectBillingPrefilled": {"additionalProperties": false, "description": "Schema for project billing prefilled data.", "properties": {"billing_lead_name": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "billing_lead_email": {"anyOf": [{"$ref": "#/components/schemas/Prefill_EmailStr_"}, {"type": "null"}]}, "billing_lead_phone": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "legal_entity": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "address": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "payment_terms": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "purchase_order_required": {"anyOf": [{"$ref": "#/components/schemas/Prefill_bool_"}, {"type": "null"}]}, "purchase_order_number": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "purchase_order_value": {"anyOf": [{"$ref": "#/components/schemas/Prefill_float_"}, {"type": "null"}]}, "currency": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "invoicing_method": {"anyOf": [{"$ref": "#/components/schemas/Prefill_InvoicingMethod_"}, {"type": "null"}]}, "invoicing_instructions": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "invoicing_email": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}, "invoice_frequency": {"anyOf": [{"$ref": "#/components/schemas/Prefill_str_"}, {"type": "null"}]}}, "title": "ProjectBillingPrefilled", "type": "object"}, "Coordinates": {"additionalProperties": false, "description": "Schema for coordinates.", "properties": {"latitude": {"title": "Latitude", "type": "number"}, "longitude": {"title": "Longitude", "type": "number"}}, "required": ["latitude", "longitude"], "title": "Coordinates", "type": "object"}, "ProjectSite": {"additionalProperties": false, "description": "Schema for project site in RFI stage.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"description": "Site name", "title": "Name", "type": "string"}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Country code in alpha-2 format", "title": "Country"}, "coordinates": {"anyOf": [{"$ref": "#/components/schemas/Coordinates"}, {"type": "null"}], "description": "Site coordinates"}, "special_conditions": {"default": [], "description": "List of special conditions for site access", "items": {"$ref": "#/components/schemas/SiteAccessConditions"}, "title": "Special Conditions", "type": "array"}, "state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State code in alpha-2 format", "title": "State"}}, "required": ["id", "name"], "title": "ProjectSite", "type": "object"}, "ProjectSites": {"additionalProperties": false, "description": "Schema for project sites.\n\nProject can contain multiple sites an each site is some collection of turbines.\nIt is not given that all turbines from the site are in the project.", "properties": {"sites": {"anyOf": [{"items": {"$ref": "#/components/schemas/ProjectSite"}, "type": "array"}, {"type": "null"}], "title": "Sites"}}, "title": "ProjectSites", "type": "object"}, "SiteAccessConditions": {"description": "Condition definitions for site.\n\nThe conditions primarily define some restrictions to access specific site.\nThey primarily drive some costs and additional services availability and pricing.", "enum": ["Unavailable technicians", "None", "Health check", "Specific permit", "Escalation fee", "Other", "5 working days", "8 working hours", "Additional technician in US", "+20% fee", "+30% fee", "+50% fee"], "title": "SiteAccessConditions", "type": "string"}, "ProjectSiteEdit": {"additionalProperties": false, "description": "Schema for project site edit in RFI stage.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Site identifier in project builder. Required when editing.", "title": "Id"}, "name": {"description": "Site name", "title": "Name", "type": "string"}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Country code in alpha-2 format", "title": "Country"}, "state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State code in alpha-2 format", "title": "State"}, "coordinates": {"anyOf": [{"$ref": "#/components/schemas/Coordinates"}, {"type": "null"}], "description": "Site coordinates"}, "special_conditions": {"description": "List of special conditions for site access. Must not be empty - if no conditions, use ['None']. 'None' cannot be selected together with other conditions.", "items": {"$ref": "#/components/schemas/SiteAccessConditions"}, "minItems": 1, "title": "Special Conditions", "type": "array"}}, "required": ["name", "special_conditions"], "title": "ProjectSiteEdit", "type": "object"}, "ProjectSitesEdit": {"additionalProperties": false, "description": "Schema for project sites update.", "properties": {"sites": {"items": {"$ref": "#/components/schemas/ProjectSiteEdit"}, "title": "Sites", "type": "array"}}, "required": ["sites"], "title": "ProjectSitesEdit", "type": "object"}, "FileAttachment": {"additionalProperties": false, "description": "File attachment response.\n\nDefines the structure of a single file uploaded to the server.", "properties": {"storage_id": {"description": "Unique identifier of the file received when first uploading it.", "format": "uuid", "title": "Storage Id", "type": "string"}, "file_name": {"description": "The name of the file.", "title": "File Name", "type": "string"}, "file_type": {"description": "MIME file type (e.g. 'application/pdf').", "title": "File Type", "type": "string"}}, "required": ["storage_id", "file_name", "file_type"], "title": "FileAttachment", "type": "object"}, "ProjectSiteAccess": {"additionalProperties": false, "description": "Schema for project site access.", "properties": {"can_work_six_days": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Can Work Six Days"}, "mandatory_certifications": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Mandatory Certifications"}, "specific_certifications_or_permits": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Specific Certifications Or Permits"}, "regional_or_country_regulations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Regional Or Country Regulations"}, "operational_limitations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Operational Limitations"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/FileAttachment"}, "title": "Attachments", "type": "array"}}, "title": "ProjectSiteAccess", "type": "object"}, "ProjectSiteAccessEdit": {"additionalProperties": false, "description": "Schema for project site access update.", "properties": {"can_work_six_days": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Can Work Six Days"}, "mandatory_certifications": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Mandatory Certifications"}, "specific_certifications_or_permits": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Specific Certifications Or Permits"}, "regional_or_country_regulations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Regional Or Country Regulations"}, "operational_limitations": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Operational Limitations"}, "attachments": {"default": [], "description": "List of file attachment storage IDs.", "items": {"format": "uuid", "type": "string"}, "title": "Attachments", "type": "array"}}, "title": "ProjectSiteAccessEdit", "type": "object"}, "AssetGroupService": {"additionalProperties": false, "description": "Single combination of asset group and it's assigned services within project.", "properties": {"group_id": {"title": "Group Id", "type": "integer"}, "count": {"title": "Count", "type": "integer"}, "type": {"$ref": "#/components/schemas/AssetGroupType"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/FileAttachment"}, "title": "Attachments", "type": "array"}, "services": {"default": [], "items": {"$ref": "#/components/schemas/AssetServiceSelection"}, "title": "Services", "type": "array"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Hub Height"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer id as in platform.", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model id as in platform.", "title": "Turbine Model Id"}, "blade_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Blade manufacturer id as in platform.", "title": "Blade Manufacturer Id"}, "blade_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Blade model id as in platform.", "title": "Blade Model Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Site to which turbine belongs to.", "title": "Site Id"}}, "required": ["group_id", "count", "type"], "title": "AssetGroupService", "type": "object"}, "AssetGroupType": {"description": "Asset group type definitions.", "enum": ["WTG", "BLADE"], "title": "AssetGroupType", "type": "string"}, "AssetServiceSelection": {"additionalProperties": false, "description": "User selection of services for particular assets.", "properties": {"code": {"description": "Unique service base code.", "title": "Code", "type": "string"}, "category": {"$ref": "#/components/schemas/CodeWithName", "description": "Service category."}, "name": {"description": "Human readable service name.", "title": "Name", "type": "string"}, "conditions": {"default": [], "description": "List of conditions that describe the service, including RAT availability.", "items": {"$ref": "#/components/schemas/ServiceCondition"}, "title": "Conditions", "type": "array"}, "addons": {"default": [], "description": "List of additional service codes that can/or are added to the service.", "items": {"type": "string"}, "title": "Addons", "type": "array"}, "materials": {"default": [], "description": "List of material codes that are compatible with the service.", "items": {"type": "string"}, "title": "Materials", "type": "array"}, "full_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full line item service code.", "title": "Full Code"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Full Name"}}, "required": ["code", "category", "name"], "title": "AssetServiceSelection", "type": "object"}, "CodeWithName": {"additionalProperties": false, "description": "Schema for code and name.", "properties": {"code": {"description": "Unique code.", "title": "Code", "type": "string"}, "name": {"description": "Human readable name.", "title": "Name", "type": "string"}}, "required": ["code", "name"], "title": "CodeWithName", "type": "object"}, "ProjectAssetGroup": {"additionalProperties": false, "description": "Schema for assets of turbines and blades and their services.", "properties": {"asset_groups": {"anyOf": [{"items": {"$ref": "#/components/schemas/AssetGroupService"}, "type": "array"}, {"type": "null"}], "title": "Asset Groups"}}, "title": "ProjectAssetGroup", "type": "object"}, "ServiceCondition": {"additionalProperties": false, "description": "Schema for service condition.", "properties": {"name": {"description": "Name of the condition specific to service.", "title": "Name", "type": "string"}, "values": {"description": "List of possible values for the condition.", "items": {"$ref": "#/components/schemas/ServiceConditionValue"}, "title": "Values", "type": "array"}}, "required": ["name", "values"], "title": "ServiceCondition", "type": "object"}, "ServiceConditionValue": {"additionalProperties": false, "description": "Schema for describing specific service condition/level.", "properties": {"code": {"description": "Unique condition value code.", "title": "Code", "type": "string"}, "name": {"description": "Human readable condition value name.", "title": "Name", "type": "string"}, "severity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Severity level for service object conditions.", "title": "Severity"}, "selected": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Selected condition by user.", "title": "Selected"}}, "required": ["code", "name"], "title": "ServiceConditionValue", "type": "object"}, "AssetGroupServiceEdit": {"additionalProperties": false, "description": "Single asset group edit on a single project.", "properties": {"group_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Asset group identifier in project builder. Required when editing.", "title": "Group Id"}, "type": {"$ref": "#/components/schemas/AssetGroupType"}, "count": {"default": 1, "description": "Number of assets in the group.", "title": "Count", "type": "integer"}, "attachments": {"default": [], "description": "List of file attachment storage IDs.", "items": {"format": "uuid", "type": "string"}, "title": "Attachments", "type": "array"}, "services": {"default": [], "items": {"$ref": "#/components/schemas/AssetServiceUserSelection"}, "title": "Services", "type": "array"}, "site_id": {"description": "Site to which turbine belongs to. Required when editing.", "title": "Site Id", "type": "integer"}, "hub_height": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Hub Height"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer id as in platform.", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model id as in platform.", "title": "Turbine Model Id"}, "blade_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Blade manufacturer id as in platform.", "title": "Blade Manufacturer Id"}, "blade_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Blade model id as in platform.", "title": "Blade Model Id"}}, "required": ["type", "site_id"], "title": "AssetGroupServiceEdit", "type": "object"}, "AssetServiceUserSelection": {"additionalProperties": false, "description": "User selection of a particular service for specific asset group.", "properties": {"code": {"description": "Selected service code.", "title": "Code", "type": "string"}, "conditions": {"description": "List of user selected conditions.", "items": {"$ref": "#/components/schemas/ServiceConditionUserSelection"}, "title": "Conditions", "type": "array"}, "materials": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Material preference.", "title": "Materials"}, "addons": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Addon services selected.", "title": "Addons"}}, "required": ["code", "conditions"], "title": "AssetServiceUserSelection", "type": "object"}, "ProjectAssetGroupEdit": {"additionalProperties": false, "description": "Schema for editing assets of turbines and blades and their services.", "properties": {"asset_groups": {"items": {"$ref": "#/components/schemas/AssetGroupServiceEdit"}, "title": "Asset Groups", "type": "array"}}, "required": ["asset_groups"], "title": "ProjectAssetGroupEdit", "type": "object"}, "ServiceConditionUserSelection": {"additionalProperties": false, "description": "User selection of service condition.", "properties": {"name": {"description": "Name of the condition that is selected.", "title": "Name", "type": "string"}, "code": {"description": "Code of the selected condition from the available values.", "title": "Code", "type": "string"}, "severity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Additional description of the service condition as a severity level.", "title": "Severity"}}, "required": ["name", "code"], "title": "ServiceConditionUserSelection", "type": "object"}, "Prefill_AssetGroupService_": {"additionalProperties": false, "properties": {"value": {"$ref": "#/components/schemas/AssetGroupService"}, "prefilled": {"default": true, "description": "Whether the value is prefilled.", "title": "Prefilled", "type": "boolean"}}, "required": ["value"], "title": "Prefill[AssetGroupService]", "type": "object"}, "ProjectAssetGroupPrefilled": {"additionalProperties": false, "description": "Schema for prefilled asset groups.", "properties": {"asset_groups": {"anyOf": [{"items": {"$ref": "#/components/schemas/Prefill_AssetGroupService_"}, "type": "array"}, {"type": "null"}], "description": "Prefilled asset groups.", "title": "Asset Groups"}}, "title": "ProjectAssetGroupPrefilled", "type": "object"}, "ProjectAsset": {"additionalProperties": false, "description": "Schema for a single project asset.", "properties": {"id": {"description": "Asset database ID", "title": "Id", "type": "integer"}, "source_asset_group": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Global group ID", "title": "Source Asset Group"}, "asset_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset identifier/name (e.g. 'WTG-1', 'BLADE-A')", "title": "Asset Id"}, "pad_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset commercial ID", "title": "Pad Id"}, "asset_type": {"description": "Type of asset (e.g. 'WTG')", "title": "Asset Type", "type": "string"}, "protected": {"description": "Whether the asset is protected from modifications", "title": "Protected", "type": "boolean"}, "changed": {"description": "Whether the asset has been changed since the table was regenerated", "title": "Changed", "type": "boolean"}, "must_have_parent": {"description": "Whether the asset must have a parent asset", "title": "Must Have Parent", "type": "boolean"}, "parent": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of parent asset, if any", "title": "Parent"}, "special_blade_group_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Count of blades in special group", "title": "Special Blade Group Count"}, "categories": {"description": "List of asset category codes", "items": {"type": "string"}, "title": "Categories", "type": "array"}, "service_codes": {"description": "List of service codes for this asset", "items": {"type": "string"}, "title": "Service Codes", "type": "array"}, "service_names": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Service Names"}, "service_fullnames": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Service Fullnames"}, "addons": {"description": "List of addons for the service", "items": {"type": "string"}, "title": "Addons", "type": "array"}, "materials": {"description": "List of materials for the service", "items": {"type": "string"}, "title": "Materials", "type": "array"}, "site": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Site name", "title": "Site"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Latitude coordinate", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Longitude coordinate", "title": "Longitude"}, "turbine_manufacturer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the turbine manufacturer (only for WTG type)", "title": "Turbine Manufacturer Name"}, "turbine_model_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the turbine model (only for WTG type)", "title": "Turbine Model Name"}, "blade_manufacturer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the blade manufacturer (only for BLADE type)", "title": "Blade Manufacturer Name"}, "blade_model_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the blade model (only for BLADE type)", "title": "Blade Model Name"}}, "required": ["id", "source_asset_group", "asset_id", "pad_id", "asset_type", "protected", "changed", "must_have_parent", "parent", "special_blade_group_count", "categories", "service_codes", "addons", "materials", "site", "latitude", "longitude"], "title": "ProjectAsset", "type": "object"}, "ProjectAssetTableResponse": {"additionalProperties": false, "description": "Schema for project assets table response.", "properties": {"assets": {"description": "List of assets with their relationships and details", "items": {"$ref": "#/components/schemas/ProjectAsset"}, "title": "Assets", "type": "array"}}, "required": ["assets"], "title": "ProjectAssetTableResponse", "type": "object"}, "ProjectAssetCreate": {"additionalProperties": false, "description": "Schema for creating a new WTG asset.", "properties": {"asset_id": {"description": "Display name/identifier of the WTG", "title": "Asset Id", "type": "string"}, "pad_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Pad ID of the WTG", "title": "Pad Id"}, "categories": {"description": "List of asset category codes", "items": {"type": "string"}, "title": "Categories", "type": "array"}, "latitude": {"description": "Latitude coordinate", "title": "Latitude", "type": "number"}, "longitude": {"description": "Longitude coordinate", "title": "Longitude", "type": "number"}, "asset_manufacturer_id": {"description": "WTG manufacturer ID", "title": "Asset Manufacturer Id", "type": "integer"}, "asset_model_id": {"description": "WTG model ID", "title": "Asset Model Id", "type": "integer"}, "service_codes": {"description": "List of service codes", "items": {"type": "string"}, "title": "Service Codes", "type": "array"}, "site": {"description": "Site ID", "title": "Site", "type": "integer"}}, "required": ["asset_id", "categories", "latitude", "longitude", "asset_manufacturer_id", "asset_model_id", "service_codes", "site"], "title": "ProjectAssetCreate", "type": "object"}, "MessageWithSuccess": {"additionalProperties": false, "description": "Success response schema with message.", "properties": {"success": {"default": true, "description": "Always true for this schema. Errors are represented by a separate Error schema, so false is never returned.", "title": "Success", "type": "boolean"}, "message": {"title": "Message", "type": "string"}}, "required": ["message"], "title": "MessageWithSuccess", "type": "object"}, "ProjectAssetPatch": {"additionalProperties": false, "description": "Schema for patching a ProjectAsset.\n\nOnly the fields that are provided will be updated.\nOther fields will remain unchanged.", "properties": {"asset_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset identifier/name (e.g. 'WTG-1', 'BLADE-A')", "title": "Asset Id"}, "pad_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset identifier/name (e.g. 'WTG-1', 'BLADE-A')", "title": "Pad Id"}, "parent": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Database ID of the parent asset (must be a WTG asset from the same project)", "title": "Parent"}, "latitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "New latitude coordinate for the asset", "title": "Latitude"}, "longitude": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "New longitude coordinate for the asset", "title": "Longitude"}}, "title": "ProjectAssetPatch", "type": "object"}, "CustomerAssetFiles": {"additionalProperties": false, "description": "Schema for customer asset files request.", "properties": {"storage_ids": {"description": "List of storage IDs from uploaded files to associate with project", "items": {"type": "string"}, "title": "Storage Ids", "type": "array"}}, "required": ["storage_ids"], "title": "CustomerAssetFiles", "type": "object"}, "CustomerAssetFilesList": {"additionalProperties": false, "description": "Schema for customer asset files response.", "properties": {"files": {"description": "List of customer asset files associated with the project", "items": {"$ref": "#/components/schemas/FileAttachment"}, "title": "Files", "type": "array"}}, "required": ["files"], "title": "CustomerAssetFilesList", "type": "object"}, "CurrencyRef": {"additionalProperties": false, "description": "Nested currency reference.", "properties": {"id": {"description": "Currency ID", "title": "Id", "type": "integer"}, "code": {"description": "Currency code", "title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "CurrencyRef", "type": "object"}, "ItemCoefficient": {"additionalProperties": false, "description": "Schema for item coefficient information.", "properties": {"type": {"description": "Type of coefficient (Country, Month, or Special Conditions)", "examples": ["Country", "Month", "Special Conditions"], "title": "Type", "type": "string"}, "name": {"description": "Name of the coefficient (e.g. country name, month name, or condition name)", "examples": ["Germany", "February", "Unavailable Technicians"], "title": "Name", "type": "string"}, "value": {"description": "Value of the coefficient", "examples": [1.1, 1.2, 1.5], "title": "Value", "type": "number"}}, "required": ["type", "name", "value"], "title": "ItemCoefficient", "type": "object"}, "LineItem": {"additionalProperties": false, "description": "Schema for offer line item.", "properties": {"persistent_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated lineage identifier alias. Use `original_item_id`.", "title": "Persistent Id"}, "row_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Unique identified of line item. Can be used to update specific line items.", "examples": [1], "title": "Row Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated duplicated line item code. Use service.code.", "examples": ["ACC"], "title": "Code"}, "category": {"$ref": "#/components/schemas/CodeWithName", "description": "Line item category with code and name", "examples": [{"code": "01INS", "name": "Inspections"}]}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Custom description for the line item", "examples": ["Emergency Mobilization Fee"], "title": "Description"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price", "examples": [100.5], "title": "Price"}, "turbine_manufacturer": {"anyOf": [{"$ref": "#/components/schemas/IDWithName"}, {"type": "null"}], "description": "Turbine manufacturer object"}, "turbine_model": {"anyOf": [{"$ref": "#/components/schemas/IDWithName"}, {"type": "null"}], "description": "Turbine model object"}, "component_manufacturer": {"anyOf": [{"$ref": "#/components/schemas/IDWithName"}, {"type": "null"}], "description": "Component manufacturer object"}, "manufacturer_component_model": {"anyOf": [{"$ref": "#/components/schemas/IDWithName"}, {"type": "null"}], "description": "Component model object"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Quantity", "examples": [5], "title": "Quantity"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount percentage", "examples": [10.5], "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price adjustment (positive or negative)", "examples": [100.5, -50.25], "title": "Adjustment"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component type name for the line item", "examples": ["Blade", "Nacelle"], "title": "Type"}, "location": {"anyOf": [{"$ref": "#/components/schemas/IDWithName"}, {"type": "null"}], "description": "Location object with id and name"}, "service": {"anyOf": [{"$ref": "#/components/schemas/ServiceRef"}, {"type": "null"}], "description": "Service object with id/code/name"}, "pricing_unit": {"anyOf": [{"$ref": "#/components/schemas/PricingUnitRef"}, {"type": "null"}], "description": "Pricing unit object with id and name"}, "coefficients": {"anyOf": [{"items": {"$ref": "#/components/schemas/ItemCoefficient"}, "type": "array"}, {"type": "null"}], "description": "List of coefficients applied to this line item (for services and addons only)", "examples": [[{"name": "Latvia", "type": "Country", "value": 1.1}, {"name": "January", "type": "Month", "value": 1.2}, {"name": "Offshore", "type": "Special Conditions", "value": 1.15}]], "title": "Coefficients"}, "group_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Asset group ID a line item belongs to.", "title": "Group Id"}, "total": {"anyOf": [{"type": "number"}, {"type": "null"}], "default": "Total price of the line item", "title": "Total"}, "unit_price": {"anyOf": [{"type": "number"}, {"type": "null"}], "default": "Unit price per asset", "title": "Unit Price"}, "original_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version lineage pointer to version 1 ancestor item", "title": "Original Item Id"}, "parent_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Deprecated parent service row id for addon/material hierarchy.", "title": "Parent Id"}, "unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated pricing unit name alias. Use `pricing_unit_id` in requests.", "examples": ["WTG", "BLADE", "MONTHLY"], "title": "Unit Type"}, "is_optional": {"default": false, "description": "Line quotes a price without a committed quantity", "examples": [true], "title": "Is Optional", "type": "boolean"}, "ler_repair_meters": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Leading edge repair length in metres", "examples": [7], "title": "Ler Repair Meters"}}, "required": ["category"], "title": "LineItem", "type": "object"}, "Offer": {"additionalProperties": false, "description": "Schema for project offer.", "properties": {"currency": {"$ref": "#/components/schemas/CurrencyRef", "description": "Offer currency object", "examples": [{"code": "EUR", "id": 1}]}, "line_items": {"description": "List of line items", "items": {"$ref": "#/components/schemas/LineItem"}, "title": "Line Items", "type": "array"}, "final_sum": {"description": "Final sum of the offer, including all line items and adjustments", "title": "Final Sum", "type": "number"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Overall discount amount applied to the original sum", "title": "Discount"}, "gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Gross margin percentage", "title": "Gross Margin"}, "adjusted_gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjusted gross margin percentage", "title": "Adjusted Gross Margin"}, "crew_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Technicians in one crew", "examples": [2], "title": "Crew Size"}, "crew_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Number of crews working the deal", "examples": [2], "title": "Crew Count"}, "working_days": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Working days on site, taken from the longest-running crew", "examples": [15.0], "title": "Working Days"}, "status": {"$ref": "#/components/schemas/OfferStatus", "description": "Status of the offer version"}, "message": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Message/reason for the offer status change (e.g., rejection reason)", "title": "Message"}}, "required": ["currency", "line_items", "final_sum", "discount", "status"], "title": "Offer", "type": "object"}, "OfferStatus": {"description": "Individual offer level status.", "enum": ["Draft", "Pending", "Approved", "Rejected"], "title": "OfferStatus", "type": "string"}, "PricingUnitRef": {"additionalProperties": false, "description": "Nested pricing unit reference.", "properties": {"id": {"description": "Pricing unit ID", "title": "Id", "type": "integer"}, "name": {"description": "Pricing unit name", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "PricingUnitRef", "type": "object"}, "ProjectOffer": {"additionalProperties": false, "description": "Schema for project offer response.", "properties": {"offer": {"$ref": "#/components/schemas/Offer", "description": "Project offer", "examples": [{"currency": {"code": "EUR", "id": 1}, "line_items": [{"category": {"code": "01INS", "name": "Inspections"}, "code": "IIN-ONS", "discount": 10.0, "location": {"id": 10, "name": "Site A"}, "price": 100.5, "quantity": 5, "row_id": 1, "service": {"code": "IIN-ONS", "id": 123, "name": "Internal inspection"}, "turbine_manufacturer": {"id": 2, "name": "Vestas"}, "turbine_model": {"id": 5, "name": "V150"}}]}]}}, "required": ["offer"], "title": "ProjectOffer", "type": "object"}, "ServiceRef": {"additionalProperties": false, "description": "Nested service reference.", "properties": {"id": {"description": "Service ID", "title": "Id", "type": "integer"}, "code": {"description": "Service code", "title": "Code", "type": "string"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service description", "title": "Name"}}, "required": ["id", "code"], "title": "ServiceRef", "type": "object"}, "OfferUpdate": {"additionalProperties": false, "description": "Schema to set commercial values on the current draft offer.", "properties": {"gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Gross margin percentage", "title": "Gross Margin"}, "adjusted_gross_margin": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Adjusted gross margin percentage", "title": "Adjusted Gross Margin"}, "crew_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Technicians in one crew", "examples": [2], "title": "Crew Size"}, "crew_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Number of crews working the deal", "examples": [2], "title": "Crew Count"}, "working_days": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Working days on site, taken from the longest-running crew", "examples": [15.0], "title": "Working Days"}}, "title": "OfferUpdate", "type": "object"}, "LineItemDiff": {"additionalProperties": false, "description": "Schema for line item differences between offer versions.", "properties": {"action": {"description": "Type of change: 'added', 'removed', 'modified', 'unchanged'", "title": "Action", "type": "string"}, "row_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Row ID of the line item", "title": "Row Id"}, "code": {"description": "Line item code", "title": "Code", "type": "string"}, "category": {"$ref": "#/components/schemas/CodeWithName", "description": "Line item category"}, "price_old": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Old price value", "title": "Price Old"}, "price_new": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "New price value", "title": "Price New"}, "quantity_old": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Old quantity value", "title": "Quantity Old"}, "quantity_new": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "New quantity value", "title": "Quantity New"}, "discount_old": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Old discount value", "title": "Discount Old"}, "discount_new": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "New discount value", "title": "Discount New"}, "adjustment_old": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Old adjustment value", "title": "Adjustment Old"}, "adjustment_new": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "New adjustment value", "title": "Adjustment New"}, "description_old": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Old description value", "title": "Description Old"}, "description_new": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "New description value", "title": "Description New"}, "turbine_model": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine model", "title": "Turbine Model"}, "turbine_manufacturer": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine manufacturer", "title": "Turbine Manufacturer"}, "blade_model": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade model", "title": "Blade Model"}, "blade_manufacturer": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade manufacturer", "title": "Blade Manufacturer"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type", "title": "Type"}, "site": {"anyOf": [{"$ref": "#/components/schemas/IDWithName"}, {"type": "null"}], "description": "Site information"}}, "required": ["action", "code", "category"], "title": "LineItemDiff", "type": "object"}, "OfferChangeSummary": {"additionalProperties": false, "description": "Schema for high-level changes between offer versions.", "properties": {"manual_price_changes": {"description": "List of line item modifications (price, quantity, discount, etc.)", "items": {"type": "string"}, "title": "Manual Price Changes", "type": "array"}, "new_services": {"description": "List of new services added", "items": {"type": "string"}, "title": "New Services", "type": "array"}, "removed_services": {"description": "List of services removed", "items": {"type": "string"}, "title": "Removed Services", "type": "array"}, "price_increase": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total price increase", "title": "Price Increase"}, "price_decrease": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total price decrease", "title": "Price Decrease"}}, "required": ["manual_price_changes", "new_services", "removed_services"], "title": "OfferChangeSummary", "type": "object"}, "OfferComparison": {"additionalProperties": false, "description": "Schema for offer version comparison.", "properties": {"version1": {"description": "First version number", "title": "Version1", "type": "integer"}, "version2": {"description": "Second version number", "title": "Version2", "type": "integer"}, "currency": {"$ref": "#/components/schemas/CurrencyRef", "description": "Currency of the offers"}, "changes_summary": {"$ref": "#/components/schemas/OfferChangeSummary", "description": "Summary of changes between versions"}, "line_item_diffs": {"description": "Detailed line item differences", "items": {"$ref": "#/components/schemas/LineItemDiff"}, "title": "Line Item Diffs", "type": "array"}, "final_sum_old": {"description": "Final sum of the first version", "title": "Final Sum Old", "type": "number"}, "final_sum_new": {"description": "Final sum of the second version", "title": "Final Sum New", "type": "number"}, "version1_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Date of first version", "title": "Version1 Date"}, "version2_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Date of second version", "title": "Version2 Date"}}, "required": ["version1", "version2", "currency", "changes_summary", "line_item_diffs", "final_sum_old", "final_sum_new"], "title": "OfferComparison", "type": "object"}, "OfferApprovalRequest": {"additionalProperties": false, "description": "Schema for enhanced offer approval request.", "properties": {"sales_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales context for approver (pricing logic, discounts, etc.)", "title": "Sales Comment"}}, "title": "OfferApprovalRequest", "type": "object"}, "OfferRejectRequest": {"additionalProperties": false, "description": "Schema for offer rejection request.", "properties": {"message": {"description": "Reason for rejecting the offer", "title": "Message", "type": "string"}}, "required": ["message"], "title": "OfferRejectRequest", "type": "object"}, "ServiceLineItemCreate": {"additionalProperties": false, "description": "Schema for creating a new commercial offer line item.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "examples": [123], "title": "Service Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated service code field", "title": "Code"}, "parent_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Deprecated parent row id for addon/material hierarchy.", "title": "Parent Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "examples": [10], "title": "Location Id"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pricing unit ID", "title": "Pricing Unit Id"}, "quantity": {"description": "Quantity for the line item", "examples": [2], "title": "Quantity", "type": "integer"}, "unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated pricing unit name alias. Use `pricing_unit_id`.", "examples": ["WTG", "BLADE", "MONTHlY"], "title": "Unit Type"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount percentage for the line item", "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price adjustment for the line item", "title": "Adjustment"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Absolute price for the line item", "title": "Price"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer ID", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Turbine Model Id"}, "component_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component manufacturer ID", "title": "Component Manufacturer Id"}, "manufacturer_component_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component model ID", "title": "Manufacturer Component Model Id"}, "original_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version lineage pointer to version 1 ancestor item", "title": "Original Item Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Custom description for the line item", "title": "Description"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Quote a price without committing a quantity. The offer document keeps the line and prints its units and total as 'TBD'.", "examples": [true], "title": "Is Optional"}, "ler_repair_meters": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Leading edge repair length in metres", "examples": [7], "title": "Ler Repair Meters"}}, "required": ["quantity"], "title": "ServiceLineItemCreate", "type": "object"}, "LineItemUpdate": {"additionalProperties": false, "description": "Schema for updating a line item.\n\nBulk update is service-line-item only and row_id-based.", "properties": {"row_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Line item row_id", "title": "Row Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Legacy support-item identifier used for code-based updates", "title": "Code"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "title": "Location Id"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pricing unit ID", "title": "Pricing Unit Id"}, "unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated pricing unit name alias. Use `pricing_unit_id`.", "examples": ["WTG", "BLADE", "MONTHLY"], "title": "Unit Type"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount percentage for the line item", "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price adjustment (positive or negative) for the line item", "title": "Adjustment"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Absolute price for the line item", "title": "Price"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Quantity for the line item", "title": "Quantity"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer ID", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Turbine Model Id"}, "component_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component manufacturer ID", "title": "Component Manufacturer Id"}, "manufacturer_component_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component model ID", "title": "Manufacturer Component Model Id"}, "original_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version lineage pointer to version 1 ancestor item", "title": "Original Item Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Custom description for the line item", "examples": ["Emergency Mobilization Fee"], "title": "Description"}, "parent_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Deprecated parent row id for addon/material hierarchy.", "title": "Parent Id"}}, "title": "LineItemUpdate", "type": "object"}, "LineItemsUpdate": {"additionalProperties": false, "description": "Schema for updating multiple line items.", "properties": {"line_items": {"description": "List of line items to update", "items": {"$ref": "#/components/schemas/LineItemUpdate"}, "title": "Line Items", "type": "array"}}, "required": ["line_items"], "title": "LineItemsUpdate", "type": "object"}, "ServiceLineItemEdit": {"additionalProperties": false, "description": "Schema for editable fields on service line items.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "examples": [123], "title": "Service Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated service code field", "title": "Code"}, "parent_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Deprecated parent row id for addon/material hierarchy.", "title": "Parent Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project location ID", "examples": [10], "title": "Location Id"}, "pricing_unit_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Pricing unit ID", "title": "Pricing Unit Id"}, "quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Quantity for the line item", "examples": [2], "title": "Quantity"}, "unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Deprecated pricing unit name alias. Use `pricing_unit_id`.", "examples": ["WTG", "BLADE", "MONTHlY"], "title": "Unit Type"}, "discount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Discount percentage for the line item", "title": "Discount"}, "adjustment": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price adjustment for the line item", "title": "Adjustment"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Absolute price for the line item", "title": "Price"}, "turbine_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine manufacturer ID", "title": "Turbine Manufacturer Id"}, "turbine_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine model ID", "title": "Turbine Model Id"}, "component_manufacturer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component manufacturer ID", "title": "Component Manufacturer Id"}, "manufacturer_component_model_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component model ID", "title": "Manufacturer Component Model Id"}, "original_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Version lineage pointer to version 1 ancestor item", "title": "Original Item Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Custom description for the line item", "title": "Description"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Quote a price without committing a quantity. The offer document keeps the line and prints its units and total as 'TBD'.", "examples": [true], "title": "Is Optional"}, "ler_repair_meters": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Leading edge repair length in metres", "examples": [7], "title": "Ler Repair Meters"}}, "title": "ServiceLineItemEdit", "type": "object"}, "ProjectBTO": {"additionalProperties": false, "description": "Minimal BTO overview response schema, sourced entirely from Core.", "properties": {"project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "core.Project.code", "title": "Project Code"}, "customer": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "core.Project.requesting_customer.display_name", "title": "Customer"}, "project_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "core.Project.description", "title": "Project Description"}, "total_units": {"description": "Distinct turbines + blade components in core.ProjectScopeItem", "title": "Total Units", "type": "integer"}, "units": {"description": "Distinct turbines in core.ProjectScopeItem", "title": "Units", "type": "integer"}, "project_planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "MIN(start_date) across all of the project's planned deployments (core.ProjectPlannedResourceSetItem)", "title": "Project Planned Start Date"}, "project_planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "MAX(end_date) across all of the project's planned deployments (core.ProjectPlannedResourceSetItem)", "title": "Project Planned End Date"}, "project_managers": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "core.Project.project_manager full name", "title": "Project Managers"}, "sales_account_executives": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "core.Project.salesperson full name", "title": "Sales Account Executives"}, "junior_project_manager": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "No Core source; no longer populated", "title": "Junior Project Manager"}, "customer_email_reports": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated report-recipient emails from core.ProjectContact (REPORT_RECEPIENT role)", "title": "Customer Email Reports"}}, "required": ["total_units", "units"], "title": "ProjectBTO", "type": "object"}, "RamsDocumentResponse": {"description": "Serialised RAMS document.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"title": "Project Id", "type": "integer"}, "pprs_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Pprs Id"}, "pprs_name": {"default": "", "title": "Pprs Name", "type": "string"}, "pprs_dates_from": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pprs Dates From"}, "pprs_dates_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pprs Dates To"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "service_code": {"default": "", "title": "Service Code", "type": "string"}, "service_family_code": {"default": "", "title": "Service Family Code", "type": "string"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Template Id"}, "template_resolved_scope": {"default": "", "title": "Template Resolved Scope", "type": "string"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"default": "", "title": "Robot Set Name", "type": "string"}, "region": {"title": "Region", "type": "string"}, "location_type": {"title": "Location Type", "type": "string"}, "version": {"title": "Version", "type": "string"}, "status": {"title": "Status", "type": "string"}, "form_data": {"title": "Form Data", "type": "object"}, "prefill_snapshot": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Prefill Snapshot"}, "pre_hse_review_snapshot": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Pre Hse Review Snapshot"}, "project_location_ids": {"items": {"type": "integer"}, "title": "Project Location Ids", "type": "array"}, "comments": {"items": {}, "title": "Comments", "type": "array"}, "version_history": {"items": {}, "title": "Version History", "type": "array"}, "change_log": {"items": {}, "title": "Change Log", "type": "array"}, "created_by": {"title": "Created By", "type": "string"}, "reviewed_by": {"title": "Reviewed By", "type": "string"}, "approved_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approved At"}, "customer_status": {"title": "Customer Status", "type": "string"}, "customer_submitted_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Submitted At"}, "customer_response_deadline": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Response Deadline"}, "customer_approved_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Approved At"}, "customer_approved_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Approved By Name"}, "approval_request_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Approval Request Id"}, "client_feedback": {"title": "Client Feedback", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}, "updated_at": {"title": "Updated At", "type": "string"}}, "required": ["id", "project_id", "region", "location_type", "version", "status", "form_data", "project_location_ids", "comments", "version_history", "change_log", "created_by", "reviewed_by", "customer_status", "client_feedback", "created_at", "updated_at"], "title": "RamsDocumentResponse", "type": "object"}, "RamsDocumentCreateBody": {"description": "Body for creating a new RAMS document.", "properties": {"pprs_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Pprs Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Template Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "project_location_ids": {"items": {"type": "integer"}, "title": "Project Location Ids", "type": "array"}, "region": {"title": "Region", "type": "string"}, "location_type": {"title": "Location Type", "type": "string"}, "version": {"default": "1.0", "title": "Version", "type": "string"}, "status": {"default": "draft", "title": "Status", "type": "string"}, "form_data": {"title": "Form Data", "type": "object"}, "prefill_snapshot": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Prefill Snapshot"}}, "required": ["region", "location_type"], "title": "RamsDocumentCreateBody", "type": "object"}, "RamsSetOption": {"properties": {"pprs_id": {"title": "Pprs Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "dates_from": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Dates To"}}, "required": ["pprs_id", "name"], "title": "RamsSetOption", "type": "object"}, "RamsSetOptionsResponse": {"properties": {"sets": {"items": {"$ref": "#/components/schemas/RamsSetOption"}, "title": "Sets", "type": "array"}}, "title": "RamsSetOptionsResponse", "type": "object"}, "RamsDocumentUpdateBody": {"description": "Body for patching a RAMS document.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "version": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Version"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "form_data": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Form Data"}, "prefill_snapshot": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Prefill Snapshot"}, "comments": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Comments"}, "version_history": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Version History"}, "change_log": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Change Log"}, "reviewed_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reviewed By"}, "approved_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approved At"}, "customer_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Status"}, "customer_submitted_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Submitted At"}, "customer_response_deadline": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Response Deadline"}, "client_feedback": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Client Feedback"}, "technician_emails": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Recipient technicians for the customer_approved -> tech_review hand-off; only these get an acknowledgement row and signing email. None sends to the whole resolved roster.", "title": "Technician Emails"}}, "title": "RamsDocumentUpdateBody", "type": "object"}, "RamsTechAckSummary": {"description": "Per-technician acknowledgement summary for the internal detail panel.", "properties": {"id": {"title": "Id", "type": "integer"}, "technician_name": {"title": "Technician Name", "type": "string"}, "technician_email": {"title": "Technician Email", "type": "string"}, "sent_at": {"title": "Sent At", "type": "string"}, "acknowledged_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Acknowledged At"}}, "required": ["id", "technician_name", "technician_email", "sent_at"], "title": "RamsTechAckSummary", "type": "object"}, "AckState": {"description": "Per-person acknowledgement state on the signing roster.", "enum": ["NOT_SENT", "SENT", "SIGNED"], "title": "AckState", "type": "string"}, "RamsRosterCertificate": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "RamsRosterCertificate", "type": "object"}, "RamsRosterEntry": {"properties": {"resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "name": {"title": "Name", "type": "string"}, "email": {"title": "Email", "type": "string"}, "is_lead": {"default": false, "title": "Is Lead", "type": "boolean"}, "certificates": {"items": {"$ref": "#/components/schemas/RamsRosterCertificate"}, "title": "Certificates", "type": "array"}, "window_start": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Window Start"}, "window_end": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Window End"}, "ack_state": {"$ref": "#/components/schemas/AckState"}, "acknowledged_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Acknowledged At"}, "acknowledgement_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Acknowledgement Id"}, "additional": {"default": false, "title": "Additional", "type": "boolean"}, "former": {"default": false, "title": "Former", "type": "boolean"}}, "required": ["name", "email", "ack_state"], "title": "RamsRosterEntry", "type": "object"}, "RamsRosterResponse": {"properties": {"source": {"$ref": "#/components/schemas/RosterSource"}, "entries": {"items": {"$ref": "#/components/schemas/RamsRosterEntry"}, "title": "Entries", "type": "array"}, "required_certificates": {"items": {"$ref": "#/components/schemas/RamsRosterCertificate"}, "title": "Required Certificates", "type": "array"}, "pending_count": {"default": 0, "title": "Pending Count", "type": "integer"}, "not_sent_count": {"default": 0, "title": "Not Sent Count", "type": "integer"}}, "required": ["source"], "title": "RamsRosterResponse", "type": "object"}, "RosterSource": {"description": "Where the signing roster was derived from.", "enum": ["pprs", "manual"], "title": "RosterSource", "type": "string"}, "RamsSendSelectionBody": {"description": "Optional recipient selection for the ``send-to-new-technicians`` top-up.\n\n``technician_emails`` restricts the top-up to the chosen crew members; an\nomitted body (or ``None``) tops up every roster member with no active\nacknowledgement row, matching the pre-selection behaviour.", "properties": {"technician_emails": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Technician Emails"}}, "title": "RamsSendSelectionBody", "type": "object"}, "RamsDuplicateBody": {"description": "Body for duplicating a RAMS document.", "properties": {"pprs_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Pprs Id"}, "project_location_ids": {"items": {"type": "integer"}, "title": "Project Location Ids", "type": "array"}, "form_data": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Form Data"}, "prefill_snapshot": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Prefill Snapshot"}}, "title": "RamsDuplicateBody", "type": "object"}, "RamsAttachmentResponse": {"description": "Serialised RAMS attachment.", "properties": {"id": {"title": "Id", "type": "integer"}, "file_name": {"title": "File Name", "type": "string"}, "file_size": {"title": "File Size", "type": "integer"}, "content_type": {"title": "Content Type", "type": "string"}, "uploaded_by": {"title": "Uploaded By", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}, "share_url": {"default": "", "title": "Share Url", "type": "string"}}, "required": ["id", "file_name", "file_size", "content_type", "uploaded_by", "created_at"], "title": "RamsAttachmentResponse", "type": "object"}, "RamsApprovalResponse": {"description": "Serialised RAMS approval request.", "properties": {"id": {"title": "Id", "type": "integer"}, "rams_document_id": {"title": "Rams Document Id", "type": "integer"}, "service_type": {"title": "Service Type", "type": "string"}, "service_family_code": {"default": "", "title": "Service Family Code", "type": "string"}, "version": {"title": "Version", "type": "string"}, "status": {"title": "Status", "type": "string"}, "submitted_at": {"title": "Submitted At", "type": "string"}, "response_deadline": {"title": "Response Deadline", "type": "string"}, "responded_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Responded At"}, "client_feedback": {"default": "", "title": "Client Feedback", "type": "string"}, "client_comments": {"items": {}, "title": "Client Comments", "type": "array"}, "auto_approved": {"default": false, "title": "Auto Approved", "type": "boolean"}, "form_data_snapshot": {"title": "Form Data Snapshot", "type": "object"}, "attachments": {"items": {}, "title": "Attachments", "type": "array"}}, "required": ["id", "rams_document_id", "service_type", "version", "status", "submitted_at", "response_deadline"], "title": "RamsApprovalResponse", "type": "object"}, "RamsStatusResponse": {"description": "Lightweight status check response.", "properties": {"status": {"title": "Status", "type": "string"}, "responded_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Responded At"}, "auto_approved": {"default": false, "title": "Auto Approved", "type": "boolean"}, "client_feedback": {"default": "", "title": "Client Feedback", "type": "string"}, "client_comments": {"items": {}, "title": "Client Comments", "type": "array"}}, "required": ["status"], "title": "RamsStatusResponse", "type": "object"}, "RamsClientRespondBody": {"description": "Body for client approval / rejection.", "properties": {"status": {"description": "'approved' or 'rejected'", "title": "Status", "type": "string"}, "feedback": {"default": "", "title": "Feedback", "type": "string"}, "client_comments": {"items": {}, "title": "Client Comments", "type": "array"}}, "required": ["status"], "title": "RamsClientRespondBody", "type": "object"}, "RamsTemplateImageResponse": {"additionalProperties": false, "description": "Serialised HSE-uploaded default image.", "properties": {"id": {"title": "Id", "type": "integer"}, "slot": {"title": "Slot", "type": "string"}, "label": {"title": "Label", "type": "string"}, "file_id": {"title": "File Id", "type": "integer"}, "url": {"title": "Url", "type": "string"}}, "required": ["id", "slot", "label", "file_id", "url"], "title": "RamsTemplateImageResponse", "type": "object"}, "RamsTemplateResponse": {"additionalProperties": false, "description": "Serialised RAMS template.", "properties": {"id": {"title": "Id", "type": "integer"}, "service_family_id": {"title": "Service Family Id", "type": "integer"}, "service_family_code": {"title": "Service Family Code", "type": "string"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "service_code": {"default": "", "title": "Service Code", "type": "string"}, "region_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Region Id"}, "region_name": {"default": "", "title": "Region Name", "type": "string"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "country_name": {"default": "", "title": "Country Name", "type": "string"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "customer_name": {"default": "", "title": "Customer Name", "type": "string"}, "form_data": {"title": "Form Data", "type": "object"}, "layout": {"title": "Layout", "type": "object"}, "images": {"items": {"$ref": "#/components/schemas/RamsTemplateImageResponse"}, "title": "Images", "type": "array"}, "updated_at": {"title": "Updated At", "type": "string"}}, "required": ["id", "service_family_id", "service_family_code", "form_data", "updated_at"], "title": "RamsTemplateResponse", "type": "object"}, "RamsTemplateCreateBody": {"additionalProperties": false, "description": "Body for creating a new RAMS template.\n\n``service_family_id`` (and the optional ``service_id`` narrowing) fix *what*\nthe template is for and are immutable afterwards; region / country /\ncustomer are the editable scope.", "properties": {"service_family_id": {"title": "Service Family Id", "type": "integer"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "region_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Region Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "form_data": {"title": "Form Data", "type": "object"}, "layout": {"title": "Layout", "type": "object"}}, "required": ["service_family_id"], "title": "RamsTemplateCreateBody", "type": "object"}, "RamsTemplateResolvedResponse": {"additionalProperties": false, "description": "Resolved template content for starting a new RAMS document.", "properties": {"found": {"default": false, "title": "Found", "type": "boolean"}, "id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "service_family_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Family Id"}, "service_family_code": {"default": "", "title": "Service Family Code", "type": "string"}, "form_data": {"title": "Form Data", "type": "object"}, "layout": {"title": "Layout", "type": "object"}}, "title": "RamsTemplateResolvedResponse", "type": "object"}, "RamsTemplateScopeBody": {"additionalProperties": false, "description": "New scope for a template (region / country / customer).", "properties": {"region_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Region Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Country Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}}, "title": "RamsTemplateScopeBody", "type": "object"}, "RamsTemplateUpdateBody": {"additionalProperties": false, "description": "Body for patching a RAMS template.", "properties": {"form_data": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Form Data"}, "layout": {"anyOf": [{"type": "object"}, {"type": "null"}], "title": "Layout"}, "scope": {"anyOf": [{"$ref": "#/components/schemas/RamsTemplateScopeBody"}, {"type": "null"}]}}, "title": "RamsTemplateUpdateBody", "type": "object"}, "DailyWeatherListResponse": {"additionalProperties": false, "description": "Response schema for weather data list.", "properties": {"weather": {"description": "Weather data by date", "items": {"$ref": "#/components/schemas/DailyWeatherSchema"}, "title": "Weather", "type": "array"}, "hasCoordinates": {"description": "Whether project has site coordinates", "title": "Hascoordinates", "type": "boolean"}}, "required": ["weather", "hasCoordinates"], "title": "DailyWeatherListResponse", "type": "object"}, "DailyWeatherSchema": {"additionalProperties": false, "description": "Schema for a single day's weather data.", "properties": {"date": {"description": "Date of weather data", "format": "date", "title": "Date", "type": "string"}, "temperature": {"$ref": "#/components/schemas/TimePeriodWeather", "description": "Temperature in Celsius"}, "windSpeed": {"$ref": "#/components/schemas/TimePeriodWeather", "description": "Wind speed in m/s at 80m"}, "humidity": {"$ref": "#/components/schemas/TimePeriodWeather", "description": "Humidity percentage"}, "precipitation": {"$ref": "#/components/schemas/TimePeriodWeather", "description": "Precipitation in mm/h"}, "edited": {"description": "Which fields have been manually edited", "title": "Edited", "type": "object"}}, "required": ["date", "temperature", "windSpeed", "humidity", "precipitation"], "title": "DailyWeatherSchema", "type": "object"}, "TimePeriodWeather": {"additionalProperties": false, "description": "Weather values for a single time period.", "properties": {"morning": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Morning"}, "day": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Day"}, "afternoon": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Afternoon"}}, "title": "TimePeriodWeather", "type": "object"}, "WeatherValueUpdate": {"additionalProperties": false, "description": "Schema for updating a single weather value.", "properties": {"weather_type": {"description": "Type: temperature, windSpeed, humidity, precipitation", "title": "Weather Type", "type": "string"}, "period": {"description": "Period: morning, day, afternoon", "title": "Period", "type": "string"}, "value": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "New value", "title": "Value"}}, "required": ["weather_type", "period"], "title": "WeatherValueUpdate", "type": "object"}, "WeatherResetRequest": {"additionalProperties": false, "description": "Schema for resetting weather values to API values.", "properties": {"weather_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Type to reset, or all if not specified", "title": "Weather Type"}, "period": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Period to reset, or all if not specified", "title": "Period"}}, "title": "WeatherResetRequest", "type": "object"}, "AvailableServiceOption": {"additionalProperties": false, "description": "A service option from core.Service.", "properties": {"id": {"description": "Service ID", "title": "Id", "type": "integer"}, "code": {"description": "Service code", "title": "Code", "type": "string"}, "description": {"description": "Service description", "title": "Description", "type": "string"}}, "required": ["id", "code", "description"], "title": "AvailableServiceOption", "type": "object"}, "AvailableServicesResponse": {"additionalProperties": false, "description": "Response schema for available services.", "properties": {"services": {"description": "Available service options", "items": {"$ref": "#/components/schemas/AvailableServiceOption"}, "title": "Services", "type": "array"}}, "required": ["services"], "title": "AvailableServicesResponse", "type": "object"}, "AvailableRobotSetOption": {"additionalProperties": false, "description": "A robot set option from core.RobotSet.", "properties": {"id": {"description": "Robot set ID", "title": "Id", "type": "integer"}, "name": {"description": "Robot set name", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "AvailableRobotSetOption", "type": "object"}, "AvailableRobotSetsResponse": {"additionalProperties": false, "description": "Response schema for available robot sets.", "properties": {"robot_sets": {"description": "Available robot sets", "items": {"$ref": "#/components/schemas/AvailableRobotSetOption"}, "title": "Robot Sets", "type": "array"}}, "required": ["robot_sets"], "title": "AvailableRobotSetsResponse", "type": "object"}, "AvailableResourceOption": {"additionalProperties": false, "description": "A resource option from core.Resource.", "properties": {"id": {"description": "Resource ID", "title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Full Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource email", "title": "Email"}}, "required": ["id"], "title": "AvailableResourceOption", "type": "object"}, "AvailableResourcesResponse": {"additionalProperties": false, "description": "Response schema for available resources.", "properties": {"resources": {"description": "Available resources (technicians)", "items": {"$ref": "#/components/schemas/AvailableResourceOption"}, "title": "Resources", "type": "array"}}, "required": ["resources"], "title": "AvailableResourcesResponse", "type": "object"}, "ProjectRobotSetSchema": {"additionalProperties": false, "description": "Schema for a robotic set.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set assignment ID", "title": "Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID from core.RobotSet", "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Robot set name", "title": "Robot Set Name"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID from core.Service", "title": "Service Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code (e.g., IIN-ONS)", "title": "Service Code"}, "status": {"default": "not_assigned", "description": "Booking status", "title": "Status", "type": "string"}, "scope": {"default": 0, "description": "Scope assigned to this set", "title": "Scope", "type": "integer"}, "mobilization_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Initial mobilization date for this set", "title": "Mobilization Date"}, "resource_set_items": {"default": [], "description": "Resources (robots + technicians) from core.ProjectResourceSetItem", "items": {"$ref": "#/components/schemas/ResourceSetItemSchema"}, "title": "Resource Set Items", "type": "array"}}, "title": "ProjectRobotSetSchema", "type": "object"}, "ResourceSetItemSchema": {"additionalProperties": false, "description": "Schema for a resource set item (technician or robot from core.Resource).", "properties": {"id": {"description": "ProjectResourceSetItem ID", "title": "Id", "type": "integer"}, "resource_id": {"description": "Resource ID from core.Resource", "title": "Resource Id", "type": "integer"}, "resource_type": {"description": "Resource type: ROBOT or TECHNICIAN", "title": "Resource Type", "type": "string"}, "resource_full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Resource Full Name"}, "resource_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource email", "title": "Resource Email"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is team lead", "title": "Is Lead"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID from core.Resource (for robots only)", "title": "Robot Set Id"}}, "required": ["id", "resource_id", "resource_type"], "title": "ResourceSetItemSchema", "type": "object"}, "RobotSetsAndTeamsResponse": {"additionalProperties": false, "description": "Response schema for robot sets and teams data.", "properties": {"robot_sets": {"description": "List of project robot sets", "items": {"$ref": "#/components/schemas/ProjectRobotSetSchema"}, "title": "Robot Sets", "type": "array"}}, "required": ["robot_sets"], "title": "RobotSetsAndTeamsResponse", "type": "object"}, "ProjectRobotSetInput": {"additionalProperties": false, "description": "Input schema for a robotic set.", "properties": {"robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "status": {"default": "not_assigned", "title": "Status", "type": "string"}, "scope": {"default": 0, "title": "Scope", "type": "integer"}, "mobilization_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Mobilization Date"}, "resource_set_items": {"default": [], "description": "Resources (robots + technicians) for core.ProjectResourceSet", "items": {"$ref": "#/components/schemas/ResourceSetItemInput"}, "title": "Resource Set Items", "type": "array"}, "linked_resource_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of selected pre-created resource set from core.resource_set", "title": "Linked Resource Set Id"}}, "title": "ProjectRobotSetInput", "type": "object"}, "RobotSetsAndTeamsUpdate": {"additionalProperties": false, "description": "Update schema for robot sets and teams.", "properties": {"robot_sets": {"description": "List of robot sets to save", "items": {"$ref": "#/components/schemas/ProjectRobotSetInput"}, "title": "Robot Sets", "type": "array"}}, "required": ["robot_sets"], "title": "RobotSetsAndTeamsUpdate", "type": "object"}, "AssetsServicesCompletion": {"additionalProperties": false, "description": "Schema for assets/services forms completion data.", "properties": {"filled": {"description": "Total filled fields across all assets/services forms", "title": "Filled", "type": "integer"}, "total": {"description": "Total fields across all assets/services forms", "title": "Total", "type": "integer"}, "percentage": {"description": "Overall assets/services completion percentage (0-100)", "title": "Percentage", "type": "integer"}, "general": {"$ref": "#/components/schemas/FormCompletion", "description": "Assets/services general form completion"}, "questions": {"$ref": "#/components/schemas/FormCompletion", "description": "Service-specific questions completion"}}, "required": ["filled", "total", "percentage", "general", "questions"], "title": "AssetsServicesCompletion", "type": "object"}, "FormCompletion": {"additionalProperties": false, "description": "Schema for form completion data.", "properties": {"filled": {"description": "Number of filled fields", "title": "Filled", "type": "integer"}, "total": {"description": "Total number of fields", "title": "Total", "type": "integer"}, "percentage": {"description": "Completion percentage (0-100)", "title": "Percentage", "type": "integer"}}, "required": ["filled", "total", "percentage"], "title": "FormCompletion", "type": "object"}, "PreJobCompletion": {"additionalProperties": false, "description": "Schema for Pre-job forms completion data.", "properties": {"filled": {"description": "Total filled fields across all Pre-job forms", "title": "Filled", "type": "integer"}, "total": {"description": "Total fields across all Pre-job forms", "title": "Total", "type": "integer"}, "percentage": {"description": "Overall Pre-job completion percentage (0-100)", "title": "Percentage", "type": "integer"}, "billing": {"$ref": "#/components/schemas/FormCompletion", "description": "Pre-job billing form completion"}, "sites": {"$ref": "#/components/schemas/FormCompletion", "description": "Pre-job sites form completion"}, "assets_services": {"$ref": "#/components/schemas/AssetsServicesCompletion", "description": "Pre-job assets/services form completion"}, "site_safety": {"$ref": "#/components/schemas/FormCompletion", "description": "Pre-job site safety form completion"}}, "required": ["filled", "total", "percentage", "billing", "sites", "assets_services", "site_safety"], "title": "PreJobCompletion", "type": "object"}, "ProjectOverviewPercentages": {"additionalProperties": false, "description": "Schema for project overview completion percentages.", "properties": {"filled": {"description": "Total filled fields across all forms", "title": "Filled", "type": "integer"}, "total": {"description": "Total fields across all forms", "title": "Total", "type": "integer"}, "percentage": {"description": "Overall completion percentage (0-100)", "title": "Percentage", "type": "integer"}, "rfi": {"$ref": "#/components/schemas/RFICompletion", "description": "RFI forms completion data"}, "prejob": {"$ref": "#/components/schemas/PreJobCompletion", "description": "Pre-job forms completion data"}}, "required": ["filled", "total", "percentage", "rfi", "prejob"], "title": "ProjectOverviewPercentages", "type": "object"}, "RFICompletion": {"additionalProperties": false, "description": "Schema for RFI forms completion data.", "properties": {"filled": {"description": "Total filled fields across all RFI forms", "title": "Filled", "type": "integer"}, "total": {"description": "Total fields across all RFI forms", "title": "Total", "type": "integer"}, "percentage": {"description": "Overall RFI completion percentage (0-100)", "title": "Percentage", "type": "integer"}, "general": {"$ref": "#/components/schemas/FormCompletion", "description": "RFI general form completion"}, "billing": {"$ref": "#/components/schemas/FormCompletion", "description": "RFI billing form completion"}, "sites": {"$ref": "#/components/schemas/FormCompletion", "description": "RFI sites form completion"}, "assets_services": {"$ref": "#/components/schemas/FormCompletion", "description": "RFI assets/services form completion"}}, "required": ["filled", "total", "percentage", "general", "billing", "sites", "assets_services"], "title": "RFICompletion", "type": "object"}, "TechnicianSimple": {"additionalProperties": false, "description": "Simplified schema for technician with only essential fields.", "properties": {"id": {"description": "User ID", "title": "Id", "type": "integer"}, "name": {"description": "Full name", "maxLength": 255, "title": "Name", "type": "string"}, "email": {"description": "User email", "maxLength": 255, "title": "Email", "type": "string"}, "phone": {"description": "Contact phone number", "maxLength": 255, "title": "Phone", "type": "string"}}, "required": ["id", "name", "email", "phone"], "title": "TechnicianSimple", "type": "object"}, "DuplicateScopeItem": {"additionalProperties": false, "description": "A requested scope item that already has a live SOL (duplicate guard).", "properties": {"scope_item_id": {"description": "ProjectScopeItem ID", "title": "Scope Item Id", "type": "integer"}, "existing_sol_count": {"description": "Count of live (non-cancelled) SOLs already on this scope item", "title": "Existing Sol Count", "type": "integer"}, "existing_sol_ids": {"default": [], "description": "IDs of the live SOLs already on this scope item (for linking)", "items": {"type": "integer"}, "title": "Existing Sol Ids", "type": "array"}}, "required": ["scope_item_id", "existing_sol_count"], "title": "DuplicateScopeItem", "type": "object"}, "ScopeItemGenerationResult": {"additionalProperties": false, "description": "Result for a single scope item in service order generation.", "properties": {"scope_item_id": {"description": "The ProjectScopeItem ID from the request", "title": "Scope Item Id", "type": "integer"}, "service_order_id": {"description": "The ServiceOrderHeader ID (new or reused)", "title": "Service Order Id", "type": "integer"}, "service_order_line_id": {"description": "The created ServiceOrderLine ID", "title": "Service Order Line Id", "type": "integer"}, "workorder_ids": {"default": [], "description": "Created Workorder IDs for this scope item", "items": {"type": "integer"}, "title": "Workorder Ids", "type": "array"}}, "required": ["scope_item_id", "service_order_id", "service_order_line_id"], "title": "ScopeItemGenerationResult", "type": "object"}, "ServiceOrderGenerateResponse": {"additionalProperties": false, "description": "Response from service order generation.", "properties": {"service_order_ids": {"default": [], "description": "Created ServiceOrderHeader IDs (newly created only)", "items": {"type": "integer"}, "title": "Service Order Ids", "type": "array"}, "service_order_line_ids": {"default": [], "description": "Created ServiceOrderLine IDs", "items": {"type": "integer"}, "title": "Service Order Line Ids", "type": "array"}, "workorder_ids": {"default": [], "description": "Created Workorder IDs", "items": {"type": "integer"}, "title": "Workorder Ids", "type": "array"}, "results": {"default": [], "description": "Per-scope-item results showing parent-child relationships", "items": {"$ref": "#/components/schemas/ScopeItemGenerationResult"}, "title": "Results", "type": "array"}, "requires_confirmation": {"default": false, "description": "True when generation was refused because some scope items already have a live SOL and confirm_duplicates was not set. Nothing was created; resend with confirm_duplicates=true to proceed.", "title": "Requires Confirmation", "type": "boolean"}, "duplicate_scope_items": {"default": [], "description": "Requested scope items that already have a live SOL", "items": {"$ref": "#/components/schemas/DuplicateScopeItem"}, "title": "Duplicate Scope Items", "type": "array"}}, "title": "ServiceOrderGenerateResponse", "type": "object"}, "OptionalServiceItemGeneration": {"additionalProperties": false, "description": "Opt-in (and optionally narrow) for one optional ServiceItem.\n\nUsed by the bulk service-order generation endpoint where required\nServiceItems are auto-included; this schema describes both the opt-in\nof an optional ServiceItem AND the per-component narrowing in a single\nentry, so the ``service_item_id`` and ``turbine_component_ids`` always\nlive on the same level.", "properties": {"service_item_id": {"description": "Optional ServiceItem ID to include for this scope item.", "title": "Service Item Id", "type": "integer"}, "turbine_component_ids": {"description": "TurbineComponent IDs that should receive a workorder for this ServiceItem. Each id must belong to the scope item's turbine and match the ServiceItem's component type. Empty list = default selection (every matching component).", "items": {"type": "integer"}, "title": "Turbine Component Ids", "type": "array"}}, "required": ["service_item_id"], "title": "OptionalServiceItemGeneration", "type": "object"}, "ScopeItemGenerationConfig": {"additionalProperties": false, "description": "Configuration for generating from a single scope item.", "properties": {"scope_item_id": {"description": "ProjectScopeItem ID", "title": "Scope Item Id", "type": "integer"}, "optional_service_items": {"description": "Optional ServiceItems to opt-in for this scope item, each optionally narrowed to a subset of turbine components. Required ServiceItems are auto-included for the scope item and do not need to be listed here.", "items": {"$ref": "#/components/schemas/OptionalServiceItemGeneration"}, "title": "Optional Service Items", "type": "array"}}, "required": ["scope_item_id"], "title": "ScopeItemGenerationConfig", "type": "object"}, "ServiceOrderGenerateRequest": {"additionalProperties": false, "description": "Request payload for generating service orders.", "properties": {"items": {"description": "List of scope items with their individual generation configs", "items": {"$ref": "#/components/schemas/ScopeItemGenerationConfig"}, "title": "Items", "type": "array"}, "confirm_duplicates": {"default": false, "description": "Acknowledge generating additional SOLs for scope items that already have a live (non-cancelled) SOL. When False, such items block generation and the response returns requires_confirmation.", "title": "Confirm Duplicates", "type": "boolean"}}, "required": ["items"], "title": "ServiceOrderGenerateRequest", "type": "object"}, "GenerateLineWorkordersResponse": {"additionalProperties": false, "description": "Response from generating additional workorders for a line.", "properties": {"workorder_ids": {"default": [], "description": "IDs of the newly created workorders", "items": {"type": "integer"}, "title": "Workorder Ids", "type": "array"}}, "title": "GenerateLineWorkordersResponse", "type": "object"}, "ActivityOverride": {"additionalProperties": false, "description": "Per-ServiceItem customization of which template activities get created.", "properties": {"service_item_id": {"description": "ServiceItem ID this override applies to.", "title": "Service Item Id", "type": "integer"}, "excluded_activity_ids": {"description": "ServiceItemActivity IDs to exclude \u2014 not added to the generated workorder at all. Ignored for any activity whose template already has is_optional=False (mandatory by default), unless force_optional_activities/is_rework is set \u2014 a mandatory step cannot otherwise be excluded.", "items": {"type": "integer"}, "title": "Excluded Activity Ids", "type": "array"}, "mandatory_activity_ids": {"description": "ServiceItemActivity IDs to force mandatory (is_optional=False) on the generated WorkorderActivity, regardless of the template's own is_optional flag or force_optional_activities.", "items": {"type": "integer"}, "title": "Mandatory Activity Ids", "type": "array"}}, "required": ["service_item_id"], "title": "ActivityOverride", "type": "object"}, "ComponentOverride": {"additionalProperties": false, "description": "Per-ServiceItem narrowing of which turbine components get a workorder.\n\nUsed by the line-level workorder generation endpoint, where the caller\nalready specifies which ServiceItems to generate via ``service_item_ids``\nand this schema *additionally* narrows the component selection.", "properties": {"service_item_id": {"description": "ServiceItem ID this override applies to (must be component-level).", "title": "Service Item Id", "type": "integer"}, "turbine_component_ids": {"description": "TurbineComponent IDs that should receive a workorder for this ServiceItem. Each id must belong to the scope item's turbine and match the ServiceItem's component type. An empty list (or omitting the override entirely) falls back to the default selection \u2014 all components matching the ServiceItem's component type.", "items": {"type": "integer"}, "title": "Turbine Component Ids", "type": "array"}}, "required": ["service_item_id"], "title": "ComponentOverride", "type": "object"}, "GenerateLineWorkordersRequest": {"additionalProperties": false, "description": "Request payload for generating additional workorders from a ServiceOrderLine.", "properties": {"service_item_ids": {"description": "ServiceItem IDs to generate workorders for. Currently only optional service items are allowed.", "items": {"type": "integer"}, "title": "Service Item Ids", "type": "array"}, "component_overrides": {"anyOf": [{"items": {"$ref": "#/components/schemas/ComponentOverride"}, "type": "array"}, {"type": "null"}], "description": "Optional narrowing of which turbine components get a workorder for each component-level ServiceItem. ServiceItems not listed (or listed with an empty list) use the default scope-item-driven selection.", "title": "Component Overrides"}, "activity_overrides": {"anyOf": [{"items": {"$ref": "#/components/schemas/ActivityOverride"}, "type": "array"}, {"type": "null"}], "description": "Optional per-ServiceItem customization of the generated activities: exclude specific template activities and/or force others mandatory. ServiceItems not listed use the default template-driven activity set.", "title": "Activity Overrides"}, "force_optional_activities": {"default": false, "description": "When true, every generated activity is created optional regardless of its template flag. The UI sets this for lines created from a scope change, where mandatory steps may already have been completed on the pre-scope-change workorders and should not block completion of the new SOL.", "title": "Force Optional Activities", "type": "boolean"}, "is_rework": {"default": false, "description": "When true, the generated workorders are marked as rework (redoing already-completed work). Only allowed when every selected service item resolves to a FIELD_WORK/FIELD_OTHER workorder type. Optional; defaults to False.", "title": "Is Rework", "type": "boolean"}, "rework_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional free-text note for the rework. Recorded as the change_note on the generated workorders' status-change logs (and on the SOL reopen log when generating reopens a field-completed/completed line). Ignored when is_rework is false.", "title": "Rework Note"}}, "required": ["service_item_ids"], "title": "GenerateLineWorkordersRequest", "type": "object"}, "GenerationItem": {"additionalProperties": false, "description": "A ProjectScopeItem record for generation selection.", "properties": {"id": {"description": "ProjectScopeItem.id - use this for selection", "title": "Id", "type": "integer"}, "location_id": {"description": "Location ID", "title": "Location Id", "type": "integer"}, "location_name": {"description": "Location name", "title": "Location Name", "type": "string"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Turbine Name"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "TurbineComponent ID", "title": "Turbine Component Id"}, "turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "TurbineComponent serial number", "title": "Turbine Component Serial"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code", "title": "Service Code"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service name", "title": "Service Name"}, "component_count": {"description": "Number of components (e.g., blades) under this turbine", "title": "Component Count", "type": "integer"}, "estimated_workorder_count": {"description": "Estimated workorder count based on service items", "title": "Estimated Workorder Count", "type": "integer"}, "existing_sol_count": {"default": 0, "description": "Count of live (non-cancelled) SOLs already generated for this scope item", "title": "Existing Sol Count", "type": "integer"}, "workorder_breakdown": {"default": [], "description": "Breakdown of workorders per service item", "items": {"$ref": "#/components/schemas/WorkorderBreakdownItem"}, "title": "Workorder Breakdown", "type": "array"}}, "required": ["id", "location_id", "location_name", "component_count", "estimated_workorder_count"], "title": "GenerationItem", "type": "object"}, "GenerationLocation": {"additionalProperties": false, "description": "Location option for generation filter dropdown.", "properties": {"id": {"description": "Location ID", "title": "Id", "type": "integer"}, "name": {"description": "Location name", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "GenerationLocation", "type": "object"}, "GenerationService": {"additionalProperties": false, "description": "Service option for generation filter dropdown.", "properties": {"id": {"description": "Service ID", "title": "Id", "type": "integer"}, "code": {"description": "Service code", "title": "Code", "type": "string"}, "name": {"description": "Service name", "title": "Name", "type": "string"}, "service_items": {"description": "Service items (workorder types) for this service", "items": {"$ref": "#/components/schemas/GenerationServiceItem"}, "title": "Service Items", "type": "array"}, "required_workorder_count": {"description": "Count of required (non-optional) service items", "title": "Required Workorder Count", "type": "integer"}, "optional_workorder_count": {"description": "Count of optional service items", "title": "Optional Workorder Count", "type": "integer"}}, "required": ["id", "code", "name", "service_items", "required_workorder_count", "optional_workorder_count"], "title": "GenerationService", "type": "object"}, "GenerationServiceItem": {"additionalProperties": false, "description": "Service item info for workorder generation preview.", "properties": {"id": {"description": "ServiceItem ID", "title": "Id", "type": "integer"}, "code": {"description": "ServiceItem code", "title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ServiceItem description", "title": "Description"}, "is_optional": {"description": "Whether this service item is optional", "title": "Is Optional", "type": "boolean"}, "service_id": {"description": "Parent Service ID", "title": "Service Id", "type": "integer"}, "component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID (if component-specific)", "title": "Component Id"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component type name (e.g., 'Blade') - NULL means turbine-level", "title": "Component Name"}}, "required": ["id", "code", "is_optional", "service_id"], "title": "GenerationServiceItem", "type": "object"}, "ServiceOrderGenerationDataResponse": {"additionalProperties": false, "description": "Response for GET generation data endpoint.", "properties": {"items": {"description": "Selectable ProjectScopeItem records", "items": {"$ref": "#/components/schemas/GenerationItem"}, "title": "Items", "type": "array"}, "total": {"description": "Total count of selectable records", "title": "Total", "type": "integer"}, "locations": {"description": "Location filter options", "items": {"$ref": "#/components/schemas/GenerationLocation"}, "title": "Locations", "type": "array"}, "services": {"description": "Service filter options", "items": {"$ref": "#/components/schemas/GenerationService"}, "title": "Services", "type": "array"}, "existing_service_orders_count": {"description": "Number of existing service orders for this project", "title": "Existing Service Orders Count", "type": "integer"}}, "required": ["items", "total", "locations", "services", "existing_service_orders_count"], "title": "ServiceOrderGenerationDataResponse", "type": "object"}, "TurbineComponentOption": {"additionalProperties": false, "description": "A selectable turbine component for workorder generation.", "properties": {"id": {"description": "TurbineComponent ID", "title": "Id", "type": "integer"}, "serial_number": {"description": "Component serial number", "title": "Serial Number", "type": "string"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Position (e.g., 'A', 'B', 'C')", "title": "Position"}, "label": {"description": "Display label (position or serial number)", "title": "Label", "type": "string"}}, "required": ["id", "serial_number", "label"], "title": "TurbineComponentOption", "type": "object"}, "WorkorderBreakdownItem": {"additionalProperties": false, "description": "Breakdown of workorders per service item with selectable components.", "properties": {"service_item_id": {"description": "ServiceItem ID", "title": "Service Item Id", "type": "integer"}, "service_item_code": {"description": "ServiceItem code", "title": "Service Item Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ServiceItem description", "title": "Description"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component type (e.g., 'Blade') or null for turbine-level", "title": "Component Name"}, "component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID", "title": "Component Id"}, "is_optional": {"description": "Whether this service item is optional", "title": "Is Optional", "type": "boolean"}, "components": {"default": [], "description": "Selectable turbine components (empty for turbine-level items)", "items": {"$ref": "#/components/schemas/TurbineComponentOption"}, "title": "Components", "type": "array"}}, "required": ["service_item_id", "service_item_code", "is_optional"], "title": "WorkorderBreakdownItem", "type": "object"}, "FieldCompletedAtDebug": {"additionalProperties": false, "description": "Tooltip data for SOL field_completed_at.", "properties": {"from_status_log": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "From SOL status change log (FIELD_COMPLETED transition)", "title": "From Status Log"}}, "title": "FieldCompletedAtDebug", "type": "object"}, "LineCompletedAtDebug": {"additionalProperties": false, "description": "Tooltip data for SOL completed_at (office finalization).", "properties": {"completed_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "SOL.completed_date (set during office finalization)", "title": "Completed Date"}, "from_status_log": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "From SOL status change log (COMPLETED transition)", "title": "From Status Log"}}, "title": "LineCompletedAtDebug", "type": "object"}, "ProjectServiceOrderListItem": {"additionalProperties": false, "description": "Service order line for paginated list (without nested workorders).", "properties": {"id": {"description": "ServiceOrderLine ID", "title": "Id", "type": "integer"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ServiceOrderHeader ID", "title": "Service Order Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Turbine Name"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Location name", "title": "Location Name"}, "service_code": {"description": "Service code", "title": "Service Code", "type": "string"}, "service_name": {"description": "Service name", "title": "Service Name", "type": "string"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID the line is pinned to", "title": "Turbine Component Id"}, "turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component serial number", "title": "Turbine Component Serial"}, "turbine_component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component position", "title": "Turbine Component Position"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component type name", "title": "Component Type Name"}, "workorder_count": {"description": "Number of workorders", "title": "Workorder Count", "type": "integer"}, "workorder_turbine_component_ids": {"description": "Distinct turbine_component_id values across the line's non-deleted workorders (any status, cancelled included). Lets the scope-change create drawer tell whether a whole-turbine line still has any blade left to scope change without fetching every line's workorders.", "items": {"type": "integer"}, "title": "Workorder Turbine Component Ids", "type": "array"}, "warranty_sol_count": {"default": 0, "description": "Number of warranty SOLs derived from this line", "title": "Warranty Sol Count", "type": "integer"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service order line status", "title": "Status"}, "field_completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When field work was completed", "title": "Field Completed At"}, "field_completed_at_debug": {"anyOf": [{"$ref": "#/components/schemas/FieldCompletedAtDebug"}, {"type": "null"}], "description": "Field completed timestamp source"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When office finalization occurred", "title": "Completed At"}, "completed_at_debug": {"anyOf": [{"$ref": "#/components/schemas/LineCompletedAtDebug"}, {"type": "null"}], "description": "Office finalization timestamp source"}, "original_sol_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Original SOL this line reworks (warranty work)", "title": "Original Sol Id"}, "original_sol_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Original SOL number", "title": "Original Sol Number"}, "original_sol_project_builder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Builder UUID of the original SOL's project (frontend routing)", "title": "Original Sol Project Builder Id"}}, "required": ["id", "service_code", "service_name", "workorder_count", "created_at"], "title": "ProjectServiceOrderListItem", "type": "object"}, "ServiceOrderDeleteCounts": {"additionalProperties": false, "description": "Deletion counts for service order cleanup.", "properties": {"workorder_activities": {"description": "Number of workorder activities deleted", "title": "Workorder Activities", "type": "integer"}, "workorders": {"description": "Number of workorders deleted", "title": "Workorders", "type": "integer"}, "service_order_lines": {"description": "Number of service order lines deleted", "title": "Service Order Lines", "type": "integer"}, "service_order_headers": {"description": "Number of service order headers deleted", "title": "Service Order Headers", "type": "integer"}}, "required": ["workorder_activities", "workorders", "service_order_lines", "service_order_headers"], "title": "ServiceOrderDeleteCounts", "type": "object"}, "ServiceOrderDeleteResponse": {"additionalProperties": false, "description": "Response for service order deletion.", "properties": {"success": {"description": "Whether deletion was successful", "title": "Success", "type": "boolean"}, "deleted": {"$ref": "#/components/schemas/ServiceOrderDeleteCounts", "description": "Counts of deleted records"}}, "required": ["success", "deleted"], "title": "ServiceOrderDeleteResponse", "type": "object"}, "ServiceOrderHeaderOption": {"additionalProperties": false, "description": "Compact service order header for filter dropdowns.", "properties": {"id": {"description": "ServiceOrderHeader PK", "title": "Id", "type": "integer"}, "label": {"description": "Display label (service_order_number or id)", "title": "Label", "type": "string"}}, "required": ["id", "label"], "title": "ServiceOrderHeaderOption", "type": "object"}, "ServiceOrderLocation": {"additionalProperties": false, "description": "Location summary for service order page.", "properties": {"id": {"description": "Location ID", "title": "Id", "type": "integer"}, "name": {"description": "Location name", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ServiceOrderLocation", "type": "object"}, "ServiceOrderSummaryResponse": {"additionalProperties": false, "description": "Response for GET service order summary endpoint.", "properties": {"customer": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Customer name", "title": "Customer"}, "services": {"default": [], "description": "List of unique service codes", "items": {"type": "string"}, "title": "Services", "type": "array"}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Country name", "title": "Country"}, "state": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "State/region or 'Multiple'", "title": "State"}, "project_manager": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project manager full name", "title": "Project Manager"}, "total_service_orders": {"description": "Total count of service orders", "title": "Total Service Orders", "type": "integer"}, "locations": {"default": [], "description": "Available locations", "items": {"$ref": "#/components/schemas/ServiceOrderLocation"}, "title": "Locations", "type": "array"}, "statuses": {"default": [], "description": "Distinct service order line statuses", "items": {"type": "string"}, "title": "Statuses", "type": "array"}, "service_order_headers": {"default": [], "description": "Distinct service order headers for filter dropdowns", "items": {"$ref": "#/components/schemas/ServiceOrderHeaderOption"}, "title": "Service Order Headers", "type": "array"}, "original_sols": {"default": [], "description": "Distinct original SOLs reworked in this project (warranty filter)", "items": {"$ref": "#/components/schemas/ServiceOrderHeaderOption"}, "title": "Original Sols", "type": "array"}, "warranty_project_builder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Builder UUID of this project's warranty sibling, if any", "title": "Warranty Project Builder Id"}}, "required": ["total_service_orders"], "title": "ServiceOrderSummaryResponse", "type": "object"}, "CustomerCustomFieldResponse": {"additionalProperties": false, "description": "A customer custom field definition, as any record's REST surface returns it.\n\nSerialized straight from a ``core.CustomerCustomField`` row. ``options`` is\nwhat the field offers on the record it is being returned for; see\n``resolve_options``.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Custom field ID", "title": "Id", "type": "integer"}, "customer_id": {"description": "Owning customer ID", "title": "Customer Id", "type": "integer"}, "customer_display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Owning customer display name, for labelling the field group", "title": "Customer Display Name"}, "name": {"description": "Field name", "title": "Name", "type": "string"}, "type": {"description": "Field data type", "title": "Type", "type": "string"}, "options": {"anyOf": [{"items": {"$ref": "#/components/schemas/CustomerCustomFieldOption"}, "type": "array"}, {"type": "null"}], "description": "Allowed options for SELECT-type fields. A field reading its options from a live list carries the list resolved for this record.", "title": "Options"}, "options_source": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The live list a SELECT field reads its options from, or null for a field storing its own. When set, an empty options list means no value is allowed; when null, an empty list leaves the field unrestricted.", "title": "Options Source"}, "validation": {"anyOf": [{"type": "object"}, {"type": "null"}], "description": "Limits the value must satisfy, as {min, max, decimals}. Applies to NUMBER fields; decimals 0 means whole numbers only.", "title": "Validation"}}, "required": ["updated_at", "id", "customer_id", "name", "type"], "title": "CustomerCustomFieldResponse", "type": "object"}, "CustomerCustomValueResponse": {"additionalProperties": false, "description": "One stored customer custom field value, embedded in its record's response.", "properties": {"id": {"description": "Custom value ID", "title": "Id", "type": "integer"}, "custom_field_id": {"description": "Customer custom field ID", "title": "Custom Field Id", "type": "integer"}, "custom_field_name": {"description": "Field name", "title": "Custom Field Name", "type": "string"}, "custom_field_type": {"description": "Field data type", "title": "Custom Field Type", "type": "string"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Value for the field", "title": "Value"}}, "required": ["id", "custom_field_id", "custom_field_name", "custom_field_type"], "title": "CustomerCustomValueResponse", "type": "object"}, "ServiceOrderLineDetail": {"additionalProperties": false, "description": "Service order line detail response.", "properties": {"id": {"description": "ServiceOrderLine ID", "title": "Id", "type": "integer"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine ID", "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Turbine component ID", "title": "Turbine Component Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Component type ID (for filtering available components)", "title": "Component Type Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Turbine Name"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component name", "title": "Component Name"}, "turbine_component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component serial number", "title": "Turbine Component Serial"}, "turbine_component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine component position", "title": "Turbine Component Position"}, "service_code": {"description": "Service code", "title": "Service Code", "type": "string"}, "service_description": {"description": "Service description", "title": "Service Description", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service order line status", "title": "Status"}, "billable": {"default": true, "description": "Whether the line is billable (False = warranty)", "title": "Billable", "type": "boolean"}, "original_sol_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Set when this line is itself warranty work (reworks another SOL)", "title": "Original Sol Id"}, "location_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Location name", "title": "Location Name"}, "robotic_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Aggregated robotic set(s)", "title": "Robotic Set"}, "anomaly_count": {"default": 0, "description": "Number of anomalies linked to this line", "title": "Anomaly Count", "type": "integer"}, "service_result_count": {"default": 0, "description": "Number of service results linked to this line", "title": "Service Result Count", "type": "integer"}, "scope_change": {"anyOf": [{"$ref": "#/components/schemas/ServiceOrderLineScopeChange"}, {"type": "null"}], "description": "The scope change stamped on this line (the cancelled source of a whole-line change, or the line a change created). Per-blade changes that took a blade FROM this line are only in scope_changes \u2014 a source line can carry several."}, "scope_changes": {"default": [], "description": "Every scope change touching this line, newest last: the stamped one (if any) followed by one 'source' entry per approved per-blade change that moved a blade of this line onto a new SOL.", "items": {"$ref": "#/components/schemas/ServiceOrderLineScopeChange"}, "title": "Scope Changes", "type": "array"}, "warranty_service_orders": {"default": [], "description": "Warranty SOLs derived from this line (via original_sol).", "items": {"$ref": "#/components/schemas/WarrantyServiceOrderRef"}, "title": "Warranty Service Orders", "type": "array"}, "last_rework_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Most recent rework reason recorded on this line's workorders (used to pre-fill the generate modal). Null if never reworked.", "title": "Last Rework Note"}, "customer_custom_fields": {"default": [], "description": "Customer custom fields the viewer may record on this line, ordered by name, with SELECT options resolved for this line. Empty means the line shows no custom-field section.", "items": {"$ref": "#/components/schemas/CustomerCustomFieldResponse"}, "title": "Customer Custom Fields", "type": "array"}, "customer_custom_field_values": {"default": [], "description": "Values stored on those fields, minus values on fields the viewer cannot see.", "items": {"$ref": "#/components/schemas/CustomerCustomValueResponse"}, "title": "Customer Custom Field Values", "type": "array"}}, "required": ["id", "service_code", "service_description"], "title": "ServiceOrderLineDetail", "type": "object"}, "ServiceOrderLineScopeChange": {"additionalProperties": false, "description": "Scope-change context for a SOL (source or new-SOL side).", "properties": {"id": {"description": "ProjectScopeChangeRequest ID", "title": "Id", "type": "integer"}, "role": {"description": "Either 'source' or 'replacement'", "title": "Role", "type": "string"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/ServiceOrderLineScopeChangeComponent"}, {"type": "null"}], "description": "The blade the change applies to; null for whole-line changes"}, "linked_sol": {"anyOf": [{"$ref": "#/components/schemas/ServiceOrderLineScopeChangeLinkedSol"}, {"type": "null"}], "description": "The counterpart SOL on the other side of the scope change"}}, "required": ["id", "role"], "title": "ServiceOrderLineScopeChange", "type": "object"}, "ServiceOrderLineScopeChangeComponent": {"additionalProperties": false, "description": "The blade a per-blade scope change applies to.", "properties": {"id": {"description": "TurbineComponent ID", "title": "Id", "type": "integer"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade position (A/B/C)", "title": "Position"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component serial number", "title": "Serial Number"}}, "required": ["id"], "title": "ServiceOrderLineScopeChangeComponent", "type": "object"}, "ServiceOrderLineScopeChangeLinkedSol": {"additionalProperties": false, "description": "The counterpart SOL on the other side of a scope change.", "properties": {"id": {"description": "Linked ServiceOrderLine ID", "title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Linked SOL number", "title": "Number"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Linked SOL status", "title": "Status"}}, "required": ["id"], "title": "ServiceOrderLineScopeChangeLinkedSol", "type": "object"}, "WarrantyServiceOrderRef": {"additionalProperties": false, "description": "A warranty SOL derived from this line (lives in the warranty project).", "properties": {"id": {"description": "Warranty ServiceOrderLine ID", "title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Warranty SOL number", "title": "Number"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Warranty SOL status", "title": "Status"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Warranty work service code", "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Warranty work service description", "title": "Service Description"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the warranty SOL was created", "title": "Created At"}, "field_completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Field-completed timestamp from the SOL status change log", "title": "Field Completed At"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Office-finalization timestamp from SOL.completed_date", "title": "Completed At"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Warranty project (core) ID", "title": "Project Id"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Warranty project code", "title": "Project Code"}, "project_builder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Warranty project builder UUID (frontend routing)", "title": "Project Builder Id"}}, "required": ["id"], "title": "WarrantyServiceOrderRef", "type": "object"}, "CustomerCustomValueInput": {"additionalProperties": false, "description": "One value to store against a customer custom field, on the record the URL names.", "properties": {"custom_field_id": {"description": "Customer custom field ID", "title": "Custom Field Id", "type": "integer"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Value for the field. Null or empty clears it.", "title": "Value"}}, "required": ["custom_field_id"], "title": "CustomerCustomValueInput", "type": "object"}, "ServiceOrderLineCustomerCustomFieldValuesReplace": {"additionalProperties": false, "description": "The full set of customer custom field values to store on one line.\n\nReplace semantics: a field the viewer can see and leaves out is cleared, a\nfield the viewer cannot see is never touched. See\n``CustomerCustomValueManager.replace_values_sync``.", "properties": {"customer_custom_field_values": {"description": "Every value to store, one entry per field.", "items": {"$ref": "#/components/schemas/CustomerCustomValueInput"}, "title": "Customer Custom Field Values", "type": "array"}}, "required": ["customer_custom_field_values"], "title": "ServiceOrderLineCustomerCustomFieldValuesReplace", "type": "object"}, "CreateWarrantyWorkResponse": {"additionalProperties": false, "description": "Response from creating a warranty-work SOL.", "properties": {"warranty_sol_id": {"title": "Warranty Sol Id", "type": "integer"}, "warranty_sol_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Warranty Sol Number"}, "billable": {"title": "Billable", "type": "boolean"}, "service_id": {"title": "Service Id", "type": "integer"}, "original_sol_id": {"title": "Original Sol Id", "type": "integer"}, "warranty_project_id": {"title": "Warranty Project Id", "type": "integer"}, "warranty_project_code": {"title": "Warranty Project Code", "type": "string"}, "warranty_project_builder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Warranty Project Builder Id"}, "service_order_id": {"title": "Service Order Id", "type": "integer"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "project_scope_item_id": {"title": "Project Scope Item Id", "type": "integer"}, "workorder_ids": {"default": [], "items": {"type": "integer"}, "title": "Workorder Ids", "type": "array"}}, "required": ["warranty_sol_id", "billable", "service_id", "original_sol_id", "warranty_project_id", "warranty_project_code", "service_order_id", "project_scope_item_id"], "title": "CreateWarrantyWorkResponse", "type": "object"}, "CreateWarrantyWorkRequest": {"additionalProperties": false, "description": "Request payload to create a warranty-work SOL from this SOL.\n\nTargeting defaults to mirroring the original (component overrides and\nexplicit component targeting are deferred to the configure-scope surface).\nWarranty work is always non-billable (hardcoded). Workorder generation is\ndriven by service-item selection.", "properties": {"target_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service for the warranty work; defaults to the original's service.", "title": "Target Service Id"}, "service_item_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Which service items to generate workorders for. Omitted \u2192 all required items of the target service; empty list \u2192 no workorders; list \u2192 just those.", "title": "Service Item Ids"}, "component_overrides": {"anyOf": [{"items": {"$ref": "#/components/schemas/ComponentOverride"}, "type": "array"}, {"type": "null"}], "description": "Optional per-service-item narrowing to a subset of turbine components.", "title": "Component Overrides"}}, "title": "CreateWarrantyWorkRequest", "type": "object"}, "CompletedAtDebug": {"additionalProperties": false, "description": "Breakdown of how the completion timestamp was derived.", "properties": {"from_status_log": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "From WorkorderStatusLogValueChangeLog (reliable after 2026-03-15)", "title": "From Status Log"}, "from_last_activity": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Max(activities.end_datetime) \u2014 most accurate source", "title": "From Last Activity"}, "from_updated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Workorder updated_at \u2014 unreliable fallback", "title": "From Updated At"}}, "title": "CompletedAtDebug", "type": "object"}, "ServiceOrderLineWorkorder": {"additionalProperties": false, "description": "Workorder for service order line detail.", "properties": {"id": {"description": "Workorder ID", "title": "Id", "type": "integer"}, "name": {"description": "Workorder name", "title": "Name", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "WO type (FIELD, ADMIN, OFFICE, DATA_UPLOAD)", "title": "Type"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "The blade this workorder targets; null for turbine-level work (e.g. Set Up / Packing Up). The scope-change create drawer uses it to offer only blades that actually have work on the line.", "title": "Turbine Component Id"}, "activities_completed": {"description": "Completed activities", "title": "Activities Completed", "type": "integer"}, "activities_total": {"description": "Total activities", "title": "Activities Total", "type": "integer"}, "assignment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Team assignment", "title": "Assignment"}, "is_optional": {"description": "Whether workorder is optional", "title": "Is Optional", "type": "boolean"}, "is_rework": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the workorder is rework (redoing already-completed work). NULL on legacy/normal workorders.", "title": "Is Rework"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder status", "title": "Status"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Completion timestamp", "title": "Completed At"}, "completed_at_debug": {"anyOf": [{"$ref": "#/components/schemas/CompletedAtDebug"}, {"type": "null"}], "description": "Completion timestamp source breakdown"}, "cancellation_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text reason recorded when the workorder was cancelled. Sourced from the change_note of the latest WorkorderStatusChangeLog entry that transitioned the workorder into CANCELLED. Null when the workorder isn't cancelled or no note was captured (e.g. cascades).", "title": "Cancellation Reason"}, "cancelled_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name of the user who cancelled the workorder. Sourced from the same log entry as cancellation_reason. Null when the workorder isn't cancelled or the actor is unknown.", "title": "Cancelled By Name"}}, "required": ["id", "name", "activities_completed", "activities_total", "is_optional"], "title": "ServiceOrderLineWorkorder", "type": "object"}, "WorkorderDetail": {"additionalProperties": false, "description": "Workorder detail response.", "properties": {"id": {"description": "Workorder ID", "title": "Id", "type": "integer"}, "name": {"description": "Workorder name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder status", "title": "Status"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder type", "title": "Type"}, "is_rework": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the workorder is rework (redoing completed work).", "title": "Is Rework"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IANA timezone of the workorder's location, used for activity time edits", "title": "Location Timezone"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Turbine Name"}, "component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component serial number", "title": "Component Serial"}, "component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component position", "title": "Component Position"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component type name", "title": "Component Type Name"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service item code", "title": "Service Code"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service item description", "title": "Service Name"}, "resource_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource set name", "title": "Resource Set Name"}, "resources": {"description": "Assigned resources", "items": {"$ref": "#/components/schemas/WorkorderResource"}, "title": "Resources", "type": "array"}, "technician_names": {"description": "Aggregated technician names from assignments and delays", "items": {"type": "string"}, "title": "Technician Names", "type": "array"}, "cancellation_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text reason recorded when the workorder was cancelled. Sourced from the change_note of the latest WorkorderStatusChangeLog entry that transitioned the workorder into CANCELLED. Null when the workorder isn't cancelled or no note was captured (e.g. cascades).", "title": "Cancellation Reason"}, "cancelled_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name of the user who cancelled the workorder. Null when the workorder isn't cancelled or the actor is unknown.", "title": "Cancelled By Name"}, "scope_change": {"anyOf": [{"$ref": "#/components/schemas/ServiceOrderLineScopeChange"}, {"type": "null"}], "description": "Set when this workorder participates in a scope change: either it lives on a cancelled-source SOL (role=source), or it's a migrated clone on a replacement SOL whose service_item still points at the previous service (role=migrated)."}}, "required": ["id", "name"], "title": "WorkorderDetail", "type": "object"}, "WorkorderResource": {"additionalProperties": false, "description": "Resource assigned to a workorder.", "properties": {"id": {"description": "Resource ID", "title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource full name", "title": "Full Name"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ROBOT or TECHNICIAN", "title": "Resource Type"}}, "required": ["id"], "title": "WorkorderResource", "type": "object"}, "WorkorderActivityDetail": {"additionalProperties": false, "description": "Workorder activity response.", "properties": {"id": {"description": "Activity ID", "title": "Id", "type": "integer"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Activity description", "title": "Activity Description"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start datetime", "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End datetime", "title": "End Datetime"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status", "title": "Status"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the activity is optional. Null is treated as optional.", "title": "Is Optional"}, "estimated_duration": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Mirrored from the linked SIA's estimated_duration at create time (minutes). Null when no SIA template is linked. Frontend treats zero as 'instant' and renders a single 'Completed at' field.", "title": "Estimated Duration"}, "resources": {"description": "Resources assigned to this activity (snapshot)", "items": {"$ref": "#/components/schemas/WorkorderResource"}, "title": "Resources", "type": "array"}, "activity_resources": {"description": "Normalised resource assignments from the ``dispatch.workorder_activity_resources`` junction table. Empty until the cutover from the legacy ``resources`` JSON column has landed.", "items": {"$ref": "#/components/schemas/WorkorderActivityResourceLink"}, "title": "Activity Resources", "type": "array"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields data", "title": "Custom Fields"}}, "required": ["id"], "title": "WorkorderActivityDetail", "type": "object"}, "AvailableActivity": {"additionalProperties": false, "description": "Available activity option for workorder activity creation.", "properties": {"id": {"description": "Service item activity ID", "title": "Id", "type": "integer"}, "description": {"description": "Activity description", "title": "Description", "type": "string"}, "estimated_duration": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Estimated duration in minutes", "title": "Estimated Duration"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields data", "title": "Custom Fields"}}, "required": ["id", "description"], "title": "AvailableActivity", "type": "object"}, "ProjectWorkorderListItem": {"additionalProperties": false, "description": "Workorder list item for project workorders tab.", "properties": {"id": {"description": "Workorder ID", "title": "Id", "type": "integer"}, "workorder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder ID string", "title": "Workorder Id"}, "name": {"description": "Workorder name", "title": "Name", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder type", "title": "Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder status", "title": "Status"}, "service_item": {"anyOf": [{"$ref": "#/components/schemas/WorkorderNestedIdName"}, {"type": "null"}], "description": "Service item"}, "component_type": {"anyOf": [{"$ref": "#/components/schemas/WorkorderNestedIdName"}, {"type": "null"}], "description": "Component type"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/WorkorderNestedIdSerial"}, {"type": "null"}], "description": "Turbine component"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order line ID (for SERVICE workorders)", "title": "Service Order Line Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service order ID (for SERVICE workorders)", "title": "Service Order Id"}, "planned_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Planned start datetime", "title": "Planned Start Datetime"}}, "required": ["id", "name", "created_at"], "title": "ProjectWorkorderListItem", "type": "object"}, "WorkorderNestedIdName": {"additionalProperties": false, "description": "Nested object with id and name.", "properties": {"id": {"description": "ID", "title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name", "title": "Name"}}, "required": ["id"], "title": "WorkorderNestedIdName", "type": "object"}, "WorkorderNestedIdSerial": {"additionalProperties": false, "description": "Nested object with id and serial.", "properties": {"id": {"description": "ID", "title": "Id", "type": "integer"}, "serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Serial number", "title": "Serial"}}, "required": ["id"], "title": "WorkorderNestedIdSerial", "type": "object"}, "AdminWorkorderActivity": {"additionalProperties": false, "description": "Activity for admin workorder.", "properties": {"id": {"description": "Activity ID", "title": "Id", "type": "integer"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Activity description", "title": "Activity Description"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Start datetime", "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "End datetime", "title": "End Datetime"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Activity status", "title": "Status"}, "is_optional": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the activity is optional. Null is treated as optional.", "title": "Is Optional"}, "resources": {"description": "Resources assigned to this activity (snapshot)", "items": {"$ref": "#/components/schemas/WorkorderResource"}, "title": "Resources", "type": "array"}, "activity_resources": {"description": "Normalised resource assignments from the ``dispatch.workorder_activity_resources`` junction table. Empty until the cutover from the legacy ``resources`` JSON column has landed.", "items": {"$ref": "#/components/schemas/WorkorderActivityResourceLink"}, "title": "Activity Resources", "type": "array"}, "custom_fields": {"anyOf": [{"type": "object"}, {"items": {}, "type": "array"}, {"type": "null"}], "description": "Custom fields data", "title": "Custom Fields"}}, "required": ["id"], "title": "AdminWorkorderActivity", "type": "object"}, "AdminWorkorderAssignee": {"additionalProperties": false, "description": "Assignee for admin workorder.", "properties": {"id": {"description": "User ID", "title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full name", "title": "Full Name"}}, "required": ["id"], "title": "AdminWorkorderAssignee", "type": "object"}, "AdminWorkorderDetail": {"additionalProperties": false, "description": "Admin workorder detail response.", "properties": {"id": {"description": "Workorder ID", "title": "Id", "type": "integer"}, "name": {"description": "Workorder name", "title": "Name", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder status", "title": "Status"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Workorder type", "title": "Type"}, "is_rework": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the workorder is rework (redoing completed work).", "title": "Is Rework"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "IANA timezone of the workorder's location, used for activity time edits", "title": "Location Timezone"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Turbine Name"}, "component_serial": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component serial number", "title": "Component Serial"}, "component_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component position", "title": "Component Position"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Component type name", "title": "Component Type Name"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service item code", "title": "Service Code"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service item description", "title": "Service Name"}, "resource_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resource set name", "title": "Resource Set Name"}, "resources": {"description": "Assigned resources", "items": {"$ref": "#/components/schemas/WorkorderResource"}, "title": "Resources", "type": "array"}, "technician_names": {"description": "Aggregated technician names from assignments and delays", "items": {"type": "string"}, "title": "Technician Names", "type": "array"}, "planned_start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Planned start datetime", "title": "Planned Start Datetime"}, "planned_end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Planned end datetime", "title": "Planned End Datetime"}, "assignee": {"anyOf": [{"$ref": "#/components/schemas/AdminWorkorderAssignee"}, {"type": "null"}], "description": "Assigned user"}, "activities": {"description": "Workorder activities", "items": {"$ref": "#/components/schemas/AdminWorkorderActivity"}, "title": "Activities", "type": "array"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "cancellation_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text reason recorded when the workorder was cancelled. Sourced from the change_note of the latest WorkorderStatusChangeLog entry that transitioned the workorder into CANCELLED. Null when the workorder isn't cancelled or no note was captured (e.g. cascades).", "title": "Cancellation Reason"}, "cancelled_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name of the user who cancelled the workorder. Null when the workorder isn't cancelled or the actor is unknown.", "title": "Cancelled By Name"}}, "required": ["id", "name", "created_at"], "title": "AdminWorkorderDetail", "type": "object"}, "UnplannedServiceItem": {"additionalProperties": false, "description": "Unplanned service item that doesn't have a workorder yet.", "properties": {"id": {"description": "ServiceItem ID", "title": "Id", "type": "integer"}, "name": {"description": "Service item code/name", "title": "Name", "type": "string"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "WO type that this service item generates", "title": "Type"}, "activities_total": {"description": "Number of activities the template will generate", "title": "Activities Total", "type": "integer"}, "is_optional": {"description": "Whether item is optional", "title": "Is Optional", "type": "boolean"}, "component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ComponentType ID this service item is scoped to (null for turbine-level items). Used by the UI to decide whether to show a per-component picker before generation.", "title": "Component Id"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name of the component type, when set", "title": "Component Name"}}, "required": ["id", "name", "activities_total", "is_optional"], "title": "UnplannedServiceItem", "type": "object"}, "DeleteWorkorderResponse": {"additionalProperties": false, "description": "Response from deleting an unplanned workorder.", "properties": {"success": {"description": "Whether deletion succeeded", "title": "Success", "type": "boolean"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Error message if failed", "title": "Error"}}, "required": ["success"], "title": "DeleteWorkorderResponse", "type": "object"}, "StatusChangeLogEntry": {"additionalProperties": false, "description": "A single workorder status change log entry.", "properties": {"id": {"description": "Log entry ID", "title": "Id", "type": "integer"}, "old_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Previous status", "title": "Old Status"}, "new_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "New status", "title": "New Status"}, "change_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Reason code (e.g. aerotask_processor, status_cascade, manual_admin)", "title": "Change Reason"}, "change_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text note", "title": "Change Note"}, "status_changed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the status transition occurred", "title": "Status Changed At"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the log entry was created", "title": "Created At"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name of who triggered the change", "title": "Created By Name"}}, "required": ["id"], "title": "StatusChangeLogEntry", "type": "object"}, "CreateStatusChangeLogRequest": {"additionalProperties": false, "description": "Request to create a new status change log entry.", "properties": {"old_status": {"anyOf": [{"$ref": "#/components/schemas/WorkorderStatusLogValue"}, {"type": "null"}], "description": "Previous status"}, "new_status": {"$ref": "#/components/schemas/WorkorderStatusLogValue", "description": "New status"}, "status_changed_at": {"description": "When the status transition occurred (ISO 8601)", "format": "date-time", "title": "Status Changed At", "type": "string"}, "change_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free-text note", "title": "Change Note"}}, "required": ["new_status", "status_changed_at"], "title": "CreateStatusChangeLogRequest", "type": "object"}, "WorkorderStatusLogValue": {"description": "Valid workorder status values for status change log entries.", "enum": ["UNASSIGNED", "NOT_STARTED", "IN_PROGRESS", "COMPLETED", "CANCELLED"], "title": "WorkorderStatusLogValue", "type": "string"}, "SolStatusChangeLogGroup": {"additionalProperties": false, "description": "Status change log entries grouped by workorder.", "properties": {"workorder_id": {"description": "Workorder ID", "title": "Workorder Id", "type": "integer"}, "workorder_name": {"description": "Workorder name", "title": "Workorder Name", "type": "string"}, "workorder_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Current workorder status", "title": "Workorder Status"}, "entries": {"description": "Status change log entries for this workorder", "items": {"$ref": "#/components/schemas/StatusChangeLogEntry"}, "title": "Entries", "type": "array"}}, "required": ["workorder_id", "workorder_name"], "title": "SolStatusChangeLogGroup", "type": "object"}, "BulkCreateStatusChangeLogRequest": {"additionalProperties": false, "description": "Request to bulk-create status change log entries for multiple workorders.", "properties": {"workorder_ids": {"description": "Workorder IDs to create entries for", "items": {"type": "integer"}, "title": "Workorder Ids", "type": "array"}, "entries": {"description": "Entries to create for each workorder", "items": {"$ref": "#/components/schemas/CreateStatusChangeLogRequest"}, "title": "Entries", "type": "array"}}, "required": ["workorder_ids", "entries"], "title": "BulkCreateStatusChangeLogRequest", "type": "object"}, "BulkDeleteStatusChangeLogRequest": {"additionalProperties": false, "description": "Request to bulk soft-delete status change log entries.", "properties": {"entry_ids": {"description": "IDs of status change log entries to delete", "items": {"type": "integer"}, "title": "Entry Ids", "type": "array"}}, "required": ["entry_ids"], "title": "BulkDeleteStatusChangeLogRequest", "type": "object"}, "TeamRequestLocationRef": {"additionalProperties": false, "properties": {"project_location_id": {"title": "Project Location Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["project_location_id", "name"], "title": "TeamRequestLocationRef", "type": "object"}, "TeamRequestResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "display_id": {"title": "Display Id", "type": "string"}, "project_id": {"title": "Project Id", "type": "integer"}, "project_location_id": {"title": "Project Location Id", "type": "integer"}, "project_location_ids": {"description": "Full site set: primary project_location_id first, then additional sites.", "items": {"type": "integer"}, "title": "Project Location Ids", "type": "array"}, "project_locations": {"description": "Full site set with display names, in the same order as project_location_ids (primary first).", "items": {"$ref": "#/components/schemas/TeamRequestLocationRef"}, "title": "Project Locations", "type": "array"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Primary service (first of ``services``), kept for back-compat.", "title": "Service Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "services": {"description": "Every service this TR's set will perform, primary first.", "items": {"$ref": "#/components/schemas/TeamRequestServiceRef"}, "title": "Services", "type": "array"}, "service_ids": {"description": "Ids of ``services``, in the same order (primary first).", "items": {"type": "integer"}, "title": "Service Ids", "type": "array"}, "pprs_id": {"title": "Pprs Id", "type": "integer"}, "people_count": {"title": "People Count", "type": "integer"}, "status": {"title": "Status", "type": "string"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "required_certificate_ids": {"items": {"type": "integer"}, "title": "Required Certificate Ids", "type": "array"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}, "mobilization_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Effective mobilization date: the linked Set Request's needed_by_date when one exists on this TR's PPRS, else the TR's own value set before any Set Request (the TR-first flow).", "title": "Mobilization Date"}, "mobilization_date_editable": {"default": false, "description": "True when the mobilization date can be set on the TR itself \u2014 no Set Request is linked yet and the TR is not cancelled. Once a Set Request exists it owns the date and this is False (read-only).", "title": "Mobilization Date Editable", "type": "boolean"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "robot_set_removed": {"default": false, "title": "Robot Set Removed", "type": "boolean"}, "wms_sync_warnings": {"items": {"type": "string"}, "title": "Wms Sync Warnings", "type": "array"}, "slots": {"items": {"$ref": "#/components/schemas/TeamRequestSlotResponse"}, "title": "Slots", "type": "array"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "display_id", "project_id", "project_location_id", "pprs_id", "people_count", "status", "updated_at"], "title": "TeamRequestResponse", "type": "object"}, "TeamRequestServiceRef": {"additionalProperties": false, "description": "One service this TR's set will perform (offer-scoped).", "properties": {"service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}}, "required": ["service_id", "service_code"], "title": "TeamRequestServiceRef", "type": "object"}, "TeamRequestSlotResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "is_lead": {"title": "Is Lead", "type": "boolean"}, "required_certificate_ids": {"items": {"type": "integer"}, "title": "Required Certificate Ids", "type": "array"}, "wms_resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Wms Resource Id"}, "wms_synced_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Wms Synced At"}, "approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Approved At"}, "rejection_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rejection Reason"}, "pprsi_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Pprsi Id"}, "pprsi_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pprsi Status"}, "pprsi_resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Pprsi Resource Id"}, "pprsi_resource_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pprsi Resource Name"}}, "required": ["id", "is_lead"], "title": "TeamRequestSlotResponse", "type": "object"}, "TeamRequestCreate": {"additionalProperties": false, "properties": {"pprs_id": {"description": "PPRS the TR is bound to.", "title": "Pprs Id", "type": "integer"}, "people_count": {"maximum": 10, "minimum": 1, "title": "People Count", "type": "integer"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "required_certificate_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Required Certificate Ids"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Legacy single-service param, kept for back-compat. Merged into ``service_ids`` when that is not supplied. Prefer ``service_ids``.", "title": "Service Id"}, "service_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Commercial-offer-scoped services this TR's set will perform (multi-select). FE picks from /site-options (all services in the project's commercial offer). Empty / omitted means no service binding yet. Server validates each id is in scope. The first id is kept as the primary ``service`` for single-service consumers.", "title": "Service Ids"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Fallback site to use when the PPRS row has a NULL project_location (Wrike sync couldn't match the windpark). Server validates the PL is on the same project, then backfills the PPRS so subsequent TR/SR against it auto-resolve. Ignored when the PPRS already has a site.", "title": "Project Location Id"}, "project_location_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Sites this TR spans (multi-select). The first id is the fallback for a PPRS with no site (same semantics as project_location_id); the resolved primary plus every other id form the TR's site set. Required certificates are the deduped union across all of them. When omitted the TR is single-site (project_location_id / PPRS).", "title": "Project Location Ids"}}, "required": ["pprs_id", "people_count"], "title": "TeamRequestCreate", "type": "object"}, "CertificateInfo": {"additionalProperties": false, "description": "A pre-job-resolved cert (a ``Certificate`` row matched by name).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "CertificateInfo", "type": "object"}, "SiteOptionsResponse": {"additionalProperties": false, "description": "Services + cert preview for a project's commercial-offer scope.\n\nServices are sourced from ``ProjectOfferItem`` rows on the project's\nlatest ``ProjectOffer``. With ``project_location_id`` the endpoint also\nreturns the pre-job cert resolution for that location: resolved\n``certificates`` (matched to a Certificate row) and\n``unresolved_certification_tokens`` (names that didn't match + free\ntext from ``other_certification_details``). The FE renders unresolved\ntokens as a warning + deep-link to pre-job; the doc-control approval\nedge is blocked while any remain.", "properties": {"services": {"items": {"$ref": "#/components/schemas/SiteServiceOption"}, "title": "Services", "type": "array"}, "certificates": {"items": {"$ref": "#/components/schemas/CertificateInfo"}, "title": "Certificates", "type": "array"}, "unresolved_certification_tokens": {"items": {"type": "string"}, "title": "Unresolved Certification Tokens", "type": "array"}}, "title": "SiteOptionsResponse", "type": "object"}, "SiteServiceOption": {"additionalProperties": false, "description": "One service priced on the project's latest commercial offer.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["id", "code"], "title": "SiteServiceOption", "type": "object"}, "RobotSetOptionResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "pprs_id": {"title": "Pprs Id", "type": "integer"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}}, "required": ["id", "name", "pprs_id"], "title": "RobotSetOptionResponse", "type": "object"}, "SetOptionsResponse": {"additionalProperties": false, "properties": {"sets": {"items": {"$ref": "#/components/schemas/RobotSetOptionResponse"}, "title": "Sets", "type": "array"}}, "title": "SetOptionsResponse", "type": "object"}, "OfferPair": {"additionalProperties": false, "properties": {"project_location_id": {"title": "Project Location Id", "type": "integer"}, "location_name": {"title": "Location Name", "type": "string"}, "service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}}, "required": ["project_location_id", "location_name", "service_id", "service_code"], "title": "OfferPair", "type": "object"}, "OfferPairsResponse": {"additionalProperties": false, "properties": {"pairs": {"items": {"$ref": "#/components/schemas/OfferPair"}, "title": "Pairs", "type": "array"}}, "title": "OfferPairsResponse", "type": "object"}, "TeamRequestUpdate": {"additionalProperties": false, "properties": {"notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "people_count": {"anyOf": [{"maximum": 10, "minimum": 1, "type": "integer"}, {"type": "null"}], "title": "People Count"}, "required_certificate_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Required Certificate Ids"}, "mobilization_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Set the TR-owned mobilization date (TR-first flow). Rejected when a Set Request is already linked \u2014 the SR owns the date then.", "title": "Mobilization Date"}, "project_location_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Full site set for the TR (DRAFT only). The primary project_location (tied to the PPRS) is always kept; any other ids become the additional sites. Editing re-derives the required certificates from the new site set.", "title": "Project Location Ids"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Legacy single-service param (DRAFT only). Merged into ``service_ids`` when that is not supplied. Prefer ``service_ids``.", "title": "Service Id"}, "service_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Full service set for the TR (DRAFT only). Replaces the current services wholesale: each id must be priced on the project's latest offer; an empty list clears them. The first id becomes the primary ``service``.", "title": "Service Ids"}}, "title": "TeamRequestUpdate", "type": "object"}, "CertDriftItem": {"additionalProperties": false, "description": "One cert that's been added or removed in pre-job vs the TR snapshot.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "CertDriftItem", "type": "object"}, "CertDriftResponse": {"additionalProperties": false, "description": "Diff between TR's required-cert snapshot and pre-job's current set.\n\n``can_apply`` reflects the FSM rule that re-syncing certs once the TR\nhas been sent to the planner would silently change the requirements\nthey're already planning against. The FE renders the banner but hides\nthe Apply button in that case.", "properties": {"added": {"items": {"$ref": "#/components/schemas/CertDriftItem"}, "title": "Added", "type": "array"}, "removed": {"items": {"$ref": "#/components/schemas/CertDriftItem"}, "title": "Removed", "type": "array"}, "unresolved_tokens": {"items": {"type": "string"}, "title": "Unresolved Tokens", "type": "array"}, "unresolved_text": {"default": "", "description": "Raw customer-typed cert blob", "title": "Unresolved Text", "type": "string"}, "can_apply": {"default": true, "title": "Can Apply", "type": "boolean"}}, "title": "CertDriftResponse", "type": "object"}, "ResolveCertTokenPayload": {"additionalProperties": false, "description": "Body for POST /team-requests/{id}/resolve-cert-token.\n\nThe doc-controller picks one unresolved token and tells the server what to\ndo with it: ``map`` it to an existing Certificate, ``create`` a fresh\nCertificate then map, or ``drop`` it (strip with no new requirement).\n\nThe token is stripped from both pre-job cert answers \u2014 the\n``required_certifications`` list and the free-text\n``other_certification_details`` \u2014 across every site the TR spans. Matching\nnothing is a 422, not a silent success.", "properties": {"matched_text": {"description": "Token to strip from the pre-job cert answers (required_certifications and/or other_certification_details)", "minLength": 1, "title": "Matched Text", "type": "string"}, "action": {"description": "What to do with the token", "enum": ["map", "create", "drop"], "title": "Action", "type": "string"}, "certificate_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing Certificate FK \u2014 required when action='map'", "title": "Certificate Id"}, "new_certificate": {"anyOf": [{"$ref": "#/components/schemas/CertificateCreate"}, {"type": "null"}], "description": "Full CertificateCreate payload \u2014 required when action='create'"}}, "required": ["matched_text", "action"], "title": "ResolveCertTokenPayload", "type": "object"}, "TeamRequestDuplicate": {"additionalProperties": false, "properties": {"pprs_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Optional override; defaults to the source TR's PPRS.", "title": "Pprs Id"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Fallback site when the target PPRS has no project_location. Same semantics as on TeamRequestCreate.", "title": "Project Location Id"}, "project_location_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Override the cloned site set. When given, the first id is the PPRS fallback and the full list becomes the duplicate's sites; when omitted, the source TR's site set is cloned.", "title": "Project Location Ids"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Legacy single-service override. Merged into ``service_ids`` when that is not supplied. Prefer ``service_ids``.", "title": "Service Id"}, "service_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Override the cloned services (each must be on the project's latest offer). When omitted, the source TR's full service set is cloned.", "title": "Service Ids"}}, "title": "TeamRequestDuplicate", "type": "object"}, "TeamRequestEventResponse": {"additionalProperties": false, "description": "One row in the unified TR timeline.\n\nCarries the union of status-change and activity fields; the\n``event_type`` discriminator tells the frontend how to render it\n(``STATUS_CHANGE`` vs an activity type like ``NOTE_ADDED``).\n\n``id`` is unique within the response across both backing tables \u2014\nactivity ids are offset by 1e9 so the frontend can use it as a stable\nReact key.", "properties": {"id": {"title": "Id", "type": "integer"}, "event_type": {"title": "Event Type", "type": "string"}, "description": {"title": "Description", "type": "string"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "resource_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Name"}, "old_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Old Status"}, "new_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "New Status"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}, "created_by_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Email"}, "mentioned_user_ids": {"items": {"type": "integer"}, "title": "Mentioned User Ids", "type": "array"}}, "required": ["id", "event_type", "description", "created_at"], "title": "TeamRequestEventResponse", "type": "object"}, "TeamRequestNoteCreate": {"additionalProperties": false, "description": "POST .../notes body \u2014 free-form note with optional @-mentions.\n\n``mentioned_user_ids`` is persisted as a sidecar list on the activity row\nso a later email-notification step can resolve recipients without\nre-parsing the note body. Order-preserving; duplicates are dropped.", "properties": {"text": {"maxLength": 4000, "minLength": 1, "title": "Text", "type": "string"}, "mentioned_user_ids": {"items": {"type": "integer"}, "title": "Mentioned User Ids", "type": "array"}}, "required": ["text"], "title": "TeamRequestNoteCreate", "type": "object"}, "TeamRequestSlotUpdate": {"additionalProperties": false, "description": "Per-slot PATCH payload. Cert-set replace + lead-transfer.", "properties": {"required_certificate_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Required Certificate Ids"}, "is_lead": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Lead"}}, "title": "TeamRequestSlotUpdate", "type": "object"}, "SlotRejectPayload": {"additionalProperties": false, "description": "POST .../slots/{id}/reject body. Reason is persisted on the slot.", "properties": {"reason": {"maxLength": 500, "minLength": 1, "title": "Reason", "type": "string"}}, "required": ["reason"], "title": "SlotRejectPayload", "type": "object"}, "ApplicabilityResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}}, "required": ["id"], "title": "ApplicabilityResponse", "type": "object"}, "ProjectRequirementResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "title": {"title": "Title", "type": "string"}, "body": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Body"}, "current_version": {"title": "Current Version", "type": "integer"}, "required_baseline_version": {"title": "Required Baseline Version", "type": "integer"}, "status": {"title": "Status", "type": "string"}, "decline_reason": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Decline Reason"}, "attachment_file_ids": {"items": {"type": "string"}, "title": "Attachment File Ids", "type": "array"}, "applicabilities": {"items": {"$ref": "#/components/schemas/ApplicabilityResponse"}, "title": "Applicabilities", "type": "array"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}, "updated_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Updated By Name"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "title", "current_version", "required_baseline_version", "status", "created_at", "updated_at"], "title": "ProjectRequirementResponse", "type": "object"}, "ApplicabilityInput": {"additionalProperties": false, "description": "Typed-FK applicability row. Scope is read from the populated columns; at\nmost one of {project_id, turbine_id}; project rows never carry customer_id.", "properties": {"project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}}, "title": "ApplicabilityInput", "type": "object"}, "ProjectRequirementCreate": {"additionalProperties": false, "properties": {"title": {"maxLength": 255, "title": "Title", "type": "string"}, "body": {"title": "Body", "type": "string"}, "attachment_file_ids": {"items": {"type": "string"}, "title": "Attachment File Ids", "type": "array"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer the requirement belongs to (null = Aerones-owned). Defaults to the URL project's requesting customer.", "title": "Customer Id"}, "applicabilities": {"description": "Explicit typed-FK rows; empty = whole project.", "items": {"$ref": "#/components/schemas/ApplicabilityInput"}, "title": "Applicabilities", "type": "array"}}, "required": ["title", "body"], "title": "ProjectRequirementCreate", "type": "object"}, "AssetOption": {"additionalProperties": false, "description": "A pickable turbine (v1 assets are turbine-only).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "AssetOption", "type": "object"}, "ProjectRequirementOptionsResponse": {"additionalProperties": false, "description": "Pickable options for the modal: services from the project's latest offer +\nturbines from its scope items. ``current_project_id`` is the resolved core id\nof the URL project (requirements are scoped to it).", "properties": {"services": {"items": {"$ref": "#/components/schemas/ServiceOption"}, "title": "Services", "type": "array"}, "assets": {"items": {"$ref": "#/components/schemas/AssetOption"}, "title": "Assets", "type": "array"}, "current_project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Current Project Id"}}, "title": "ProjectRequirementOptionsResponse", "type": "object"}, "ServiceOption": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["id", "code"], "title": "ServiceOption", "type": "object"}, "ProjectRequirementUpdate": {"additionalProperties": false, "properties": {"title": {"anyOf": [{"maxLength": 255, "type": "string"}, {"type": "null"}], "title": "Title"}, "body": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Body"}, "attachment_file_ids": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "title": "Attachment File Ids"}, "applicabilities": {"anyOf": [{"items": {"$ref": "#/components/schemas/ApplicabilityInput"}, "type": "array"}, {"type": "null"}], "title": "Applicabilities"}, "re_familiarize": {"default": true, "description": "true (default): invalidate operator familiarity \u2014 live acks are tombstoned, operators must re-acknowledge. false: carry acks forward. Applies to any edit, body or scope.", "title": "Re Familiarize", "type": "boolean"}}, "title": "ProjectRequirementUpdate", "type": "object"}, "GateCheckResponse": {"additionalProperties": false, "properties": {"familiar": {"title": "Familiar", "type": "boolean"}, "missing_requirements": {"items": {"$ref": "#/components/schemas/GateMissingRequirement"}, "title": "Missing Requirements", "type": "array"}}, "required": ["familiar"], "title": "GateCheckResponse", "type": "object"}, "GateMissingRequirement": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "title": {"title": "Title", "type": "string"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "current_version": {"title": "Current Version", "type": "integer"}}, "required": ["id", "title", "current_version"], "title": "GateMissingRequirement", "type": "object"}, "FamiliarityResponse": {"additionalProperties": false, "properties": {"requirement_id": {"title": "Requirement Id", "type": "integer"}, "user_sub": {"title": "User Sub", "type": "string"}, "version": {"title": "Version", "type": "integer"}, "familiarized_at": {"format": "date-time", "title": "Familiarized At", "type": "string"}}, "required": ["requirement_id", "user_sub", "version", "familiarized_at"], "title": "FamiliarityResponse", "type": "object"}, "FamiliarityCreate": {"additionalProperties": false, "properties": {"requirement_id": {"title": "Requirement Id", "type": "integer"}, "operator_sub": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Keycloak sub; defaults to the caller's.", "title": "Operator Sub"}}, "required": ["requirement_id"], "title": "FamiliarityCreate", "type": "object"}, "CruProjectRequirementCreate": {"additionalProperties": false, "description": "cru data-operator create. customer_id is the requirement's owning (root)\ncustomer; null for Aerones-owned / project / turbine-general requirements.", "properties": {"customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "title": {"maxLength": 255, "title": "Title", "type": "string"}, "body": {"title": "Body", "type": "string"}, "status": {"anyOf": [{"enum": ["DRAFT", "PENDING", "ACTIVE", "INACTIVE"], "type": "string"}, {"type": "null"}], "description": "Defaults to ACTIVE. DECLINED is reachable only via /decline.", "title": "Status"}, "attachment_file_ids": {"items": {"type": "string"}, "title": "Attachment File Ids", "type": "array"}, "applicabilities": {"description": "Explicit applicability rows; empty = whole customer.", "items": {"$ref": "#/components/schemas/ApplicabilityInput"}, "title": "Applicabilities", "type": "array"}}, "required": ["title", "body"], "title": "CruProjectRequirementCreate", "type": "object"}, "RequirementVersionResponse": {"additionalProperties": false, "properties": {"version": {"title": "Version", "type": "integer"}, "body": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Body"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}}, "required": ["version", "created_at"], "title": "RequirementVersionResponse", "type": "object"}, "ItemCategoryListResponse": {"additionalProperties": false, "properties": {"items": {"items": {"$ref": "#/components/schemas/ItemCategoryResponse"}, "title": "Items", "type": "array"}}, "title": "ItemCategoryListResponse", "type": "object"}, "ItemListResponse": {"additionalProperties": false, "properties": {"items": {"items": {"$ref": "#/components/schemas/ItemResponse"}, "title": "Items", "type": "array"}}, "title": "ItemListResponse", "type": "object"}, "ItemResponse": {"additionalProperties": false, "description": "One entry in the shared ``core.item`` catalog.\n\nEditable so PMs can fix typos in place instead of forking a new entry.\n``source`` is informational \u2014 the FE tags user-added rows.", "properties": {"id": {"title": "Id", "type": "integer"}, "description": {"title": "Description", "type": "string"}, "category_id": {"title": "Category Id", "type": "integer"}, "category_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category Code"}, "source": {"title": "Source", "type": "string"}}, "required": ["id", "description", "category_id", "source"], "title": "ItemResponse", "type": "object"}, "ItemCreate": {"additionalProperties": false, "properties": {"description": {"maxLength": 255, "minLength": 1, "title": "Description", "type": "string"}, "category_id": {"description": "ItemCategory id (PPE / Consumable / \u2026).", "title": "Category Id", "type": "integer"}}, "required": ["description", "category_id"], "title": "ItemCreate", "type": "object"}, "ItemUpdate": {"additionalProperties": false, "properties": {"description": {"maxLength": 255, "minLength": 1, "title": "Description", "type": "string"}}, "required": ["description"], "title": "ItemUpdate", "type": "object"}, "SetRequestInheritCandidate": {"additionalProperties": false, "description": "A prior PICKED_UP SR (any project) whose lines can seed a new\nEXISTING_SET request for the same robot set.", "properties": {"id": {"title": "Id", "type": "integer"}, "display_id": {"title": "Display Id", "type": "string"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "items": {"items": {"$ref": "#/components/schemas/SetRequestInheritCandidateItem"}, "title": "Items", "type": "array"}}, "required": ["id", "display_id", "updated_at"], "title": "SetRequestInheritCandidate", "type": "object"}, "SetRequestInheritCandidateItem": {"additionalProperties": false, "description": "One line of a prior SR, ready to copy into the create form.", "properties": {"description": {"title": "Description", "type": "string"}, "quantity": {"title": "Quantity", "type": "string"}, "unit": {"title": "Unit", "type": "string"}, "scope": {"title": "Scope", "type": "string"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "category_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category Code"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}}, "required": ["description", "quantity", "unit", "scope"], "title": "SetRequestInheritCandidateItem", "type": "object"}, "SetRequestItemSuggestion": {"additionalProperties": false, "description": "Server-suggested item / PPE line for the create modal preview.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "description": {"default": "", "title": "Description", "type": "string"}, "quantity": {"default": "0", "title": "Quantity", "type": "string"}, "unit": {"default": "", "title": "Unit", "type": "string"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "category_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category Code"}, "source": {"default": "PREFILL", "title": "Source", "type": "string"}, "scope": {"default": "PER_SET", "title": "Scope", "type": "string"}, "project_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Offer Item Id"}, "co_budget_qty": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Co Budget Qty"}, "co_budget_drawn": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Co Budget Drawn"}, "co_budget_remaining": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Co Budget Remaining"}}, "title": "SetRequestItemSuggestion", "type": "object"}, "SetRequestPrefillOptionsResponse": {"additionalProperties": false, "description": "Read-only snapshot the create modal renders.\n\nMirrors team-request's set-options shape but adds the item preview the\nPM can edit before submitting.", "properties": {"pprs_id": {"title": "Pprs Id", "type": "integer"}, "region": {"default": "EU", "description": "Standard-set region the suggestions were drawn from \u2014 the explicit request param, else derived from the project location's country.", "enum": ["EU", "NA"], "title": "Region", "type": "string"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}, "project_planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Default value for the create-modal's mobilization date picker (the robot PPRSI's planned start date).", "title": "Project Planned Start Date"}, "suggested_items": {"items": {"$ref": "#/components/schemas/SetRequestItemSuggestion"}, "title": "Suggested Items", "type": "array"}}, "required": ["pprs_id"], "title": "SetRequestPrefillOptionsResponse", "type": "object"}, "SetRequestItemResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "description": {"default": "", "title": "Description", "type": "string"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}], "default": "0", "title": "Quantity"}, "unit": {"default": "", "title": "Unit", "type": "string"}, "source": {"title": "Source", "type": "string"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Category Id"}, "category_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category Code"}, "scope": {"default": "PER_SET", "title": "Scope", "type": "string"}, "project_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Offer Item Id"}, "co_budget_qty": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Co Budget Qty"}, "co_budget_drawn": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Co Budget Drawn"}, "co_budget_remaining": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Co Budget Remaining"}}, "required": ["id", "source"], "title": "SetRequestItemResponse", "type": "object"}, "SetRequestResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "display_id": {"title": "Display Id", "type": "string"}, "project_id": {"title": "Project Id", "type": "integer"}, "project_location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Location Id"}, "service_ids": {"items": {"type": "integer"}, "title": "Service Ids", "type": "array"}, "kind": {"default": "STANDARD", "enum": ["STANDARD", "EXISTING_SET"], "title": "Kind", "type": "string"}, "region": {"default": "EU", "title": "Region", "type": "string"}, "pprs_id": {"title": "Pprs Id", "type": "integer"}, "robot_pprsi_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Pprsi Id"}, "status": {"title": "Status", "type": "string"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "needed_by_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Needed By Date"}, "planner_decision_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Planner Decision Note"}, "approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Approved At"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "set_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Set Status"}, "expected_ready_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Expected Ready Date"}, "items": {"items": {"$ref": "#/components/schemas/SetRequestItemResponse"}, "title": "Items", "type": "array"}, "related_team_request_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Related Team Request Id"}, "team_size": {"default": 0, "title": "Team Size", "type": "integer"}, "team_lead_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Team Lead Name"}, "team_lead_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Team Lead User Id"}, "required_ready_gates": {"items": {"type": "string"}, "title": "Required Ready Gates", "type": "array"}, "mro_ready_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Mro Ready At"}, "mro_ready_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Mro Ready By Name"}, "it_done_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "It Done At"}, "it_done_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "It Done By Name"}, "ppe_ready_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ppe Ready At"}, "ppe_ready_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ppe Ready By Name"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "display_id", "project_id", "pprs_id", "status", "updated_at"], "title": "SetRequestResponse", "type": "object"}, "SetRequestCreate": {"additionalProperties": false, "properties": {"robot_pprsi_id": {"description": "The ROBOT PPRSI (planned robot line) this Set Request is for. The PPRS is derived from it, so a PPRS with several sets can carry one Set Request per set.", "title": "Robot Pprsi Id", "type": "integer"}, "service_ids": {"items": {"type": "integer"}, "title": "Service Ids", "type": "array"}, "kind": {"default": "STANDARD", "enum": ["STANDARD", "EXISTING_SET"], "title": "Kind", "type": "string"}, "region": {"anyOf": [{"enum": ["EU", "NA"], "type": "string"}, {"type": "null"}], "description": "Standard-set region. Defaults server-side from the project location's country when omitted.", "title": "Region"}, "inherit_from_set_request_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Inherit From Set Request Id"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "needed_by_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Date the set must be ready on-site (mobilization date). Server defaults to the selected robot PPRSI's planned start date when omitted, and rejects the request when neither is available.", "title": "Needed By Date"}, "items": {"items": {"$ref": "#/components/schemas/SetRequestItemInput"}, "title": "Items", "type": "array"}}, "required": ["robot_pprsi_id"], "title": "SetRequestCreate", "type": "object"}, "SetRequestItemInput": {"additionalProperties": false, "description": "One item / PPE line on a Set Request payload.", "properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Existing line id (omit when adding a new line).", "title": "Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "project_offer_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Offer Item Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "", "title": "Description"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}], "default": "0", "title": "Quantity"}, "unit": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "", "title": "Unit"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source"}, "category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ItemCategory id (PPE / Consumable / \u2026).", "title": "Category Id"}, "scope": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "PER_SET (default), PER_PERSON, PER_WTG, or PER_BLADE.", "title": "Scope"}}, "title": "SetRequestItemInput", "type": "object"}, "SetRequestUpdate": {"additionalProperties": false, "properties": {"notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "needed_by_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Needed By Date"}, "kind": {"anyOf": [{"enum": ["STANDARD", "EXISTING_SET"], "type": "string"}, {"type": "null"}], "title": "Kind"}, "items": {"anyOf": [{"items": {"$ref": "#/components/schemas/SetRequestItemInput"}, "type": "array"}, {"type": "null"}], "title": "Items"}}, "title": "SetRequestUpdate", "type": "object"}, "SetRequestEventResponse": {"additionalProperties": false, "description": "One row in the unified Set Request timeline.\n\nMirrors ``TeamRequestEventResponse`` shape so the FE can render notes,\n@-mentions, and history with the same components.", "properties": {"id": {"title": "Id", "type": "integer"}, "event_type": {"title": "Event Type", "type": "string"}, "description": {"title": "Description", "type": "string"}, "old_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Old Status"}, "new_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "New Status"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}, "created_by_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Email"}, "mentioned_user_ids": {"items": {"type": "integer"}, "title": "Mentioned User Ids", "type": "array"}, "item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Item Id"}}, "required": ["id", "event_type", "description", "created_at"], "title": "SetRequestEventResponse", "type": "object"}, "SetRequestNoteCreate": {"additionalProperties": false, "description": "POST .../notes body \u2014 free-form note with optional @-mentions.", "properties": {"text": {"maxLength": 4000, "minLength": 1, "title": "Text", "type": "string"}, "item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Item Id"}, "mentioned_user_ids": {"items": {"type": "integer"}, "title": "Mentioned User Ids", "type": "array"}}, "required": ["text"], "title": "SetRequestNoteCreate", "type": "object"}, "SetRequestApproveCurrent": {"additionalProperties": false, "properties": {"planner_decision_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Planner Decision Note"}, "expected_robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "The robot set id the planner was shown. When supplied, the server rejects the approval if the set changed since \u2014 forcing a re-review rather than approving a stale set.", "title": "Expected Robot Set Id"}}, "title": "SetRequestApproveCurrent", "type": "object"}, "SetRequestChangeAndApprove": {"additionalProperties": false, "properties": {"robot_set_id": {"description": "The robot set to approve.", "title": "Robot Set Id", "type": "integer"}, "planner_decision_note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Planner Decision Note"}}, "required": ["robot_set_id"], "title": "SetRequestChangeAndApprove", "type": "object"}, "SetRequestReject": {"additionalProperties": false, "properties": {"reason": {"description": "Why the request is rejected. Required.", "minLength": 1, "title": "Reason", "type": "string"}, "expected_robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "The robot set id the planner was shown. When supplied, the server rejects the action if the set changed since \u2014 forcing a re-review rather than rejecting a stale set.", "title": "Expected Robot Set Id"}}, "required": ["reason"], "title": "SetRequestReject", "type": "object"}, "SetRequestReadinessToggle": {"additionalProperties": false, "properties": {"confirmed": {"default": true, "description": "True to confirm this readiness step, False to undo it.", "title": "Confirmed", "type": "boolean"}}, "title": "SetRequestReadinessToggle", "type": "object"}, "SetDemobResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "display_id": {"title": "Display Id", "type": "string"}, "project_id": {"title": "Project Id", "type": "integer"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "pprs_id": {"title": "Pprs Id", "type": "integer"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "status": {"title": "Status", "type": "string"}, "is_manual": {"default": false, "title": "Is Manual", "type": "boolean"}, "demob_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Demob Date"}, "auto_demob_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Auto Demob Date"}, "date_overridden": {"default": false, "title": "Date Overridden", "type": "boolean"}, "has_date_drift": {"default": false, "title": "Has Date Drift", "type": "boolean"}, "gap_days": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Gap Days"}, "next_pprs_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Next Pprs Id"}, "next_project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Next Project Code"}, "approved_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Approved At"}, "approved_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approved By Name"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "display_id", "project_id", "pprs_id", "status", "updated_at"], "title": "SetDemobResponse", "type": "object"}, "SetDemobCreate": {"additionalProperties": false, "properties": {"pprsi_id": {"description": "The ROBOT PPRSI (robot-set deployment line) to anchor the demob on. The demob is bound to that line's parent PPRS.", "title": "Pprsi Id", "type": "integer"}, "demob_date": {"description": "The PM-committed demobilization date (the project end date), stored as the override. Must be today or later.", "format": "date", "title": "Demob Date", "type": "string"}, "note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Note"}}, "required": ["pprsi_id", "demob_date"], "title": "SetDemobCreate", "type": "object"}, "SetDemobAnchorCandidate": {"additionalProperties": false, "description": "A ROBOT PPRSI a manual demob can be anchored on (picker option).", "properties": {"pprsi_id": {"title": "Pprsi Id", "type": "integer"}, "pprs_id": {"title": "Pprs Id", "type": "integer"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "End Date"}}, "required": ["pprsi_id", "pprs_id"], "title": "SetDemobAnchorCandidate", "type": "object"}, "SetDemobEventResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "event_type": {"title": "Event Type", "type": "string"}, "old_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Old Status"}, "new_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "New Status"}, "old_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Old Date"}, "new_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "New Date"}, "description": {"default": "", "title": "Description", "type": "string"}, "actor_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Actor Name"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "event_type", "updated_at"], "title": "SetDemobEventResponse", "type": "object"}, "SetDemobApprove": {"additionalProperties": false, "properties": {"demob_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Return date to confirm. Defaults to the set's PPRSI end date (auto_demob_date) when omitted.", "title": "Demob Date"}, "note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Note"}}, "title": "SetDemobApprove", "type": "object"}, "SetDemobAdjustDate": {"additionalProperties": false, "properties": {"demob_date": {"description": "The corrected return date.", "format": "date", "title": "Demob Date", "type": "string"}, "note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Note"}}, "required": ["demob_date"], "title": "SetDemobAdjustDate", "type": "object"}, "SetDemobReject": {"additionalProperties": false, "properties": {"reason": {"description": "Why this demob is rejected. Required.", "minLength": 1, "title": "Reason", "type": "string"}}, "required": ["reason"], "title": "SetDemobReject", "type": "object"}, "SetDemobCancel": {"additionalProperties": false, "properties": {"note": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Note"}}, "title": "SetDemobCancel", "type": "object"}, "ProjectMeta": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "project_builder_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Builder Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Customer Name"}, "pm_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Pm Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "required": ["id", "project_builder_id", "code", "customer_name", "pm_name", "status"], "title": "ProjectMeta", "type": "object"}, "RamsDocumentReadinessRow": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "status": {"title": "Status", "type": "string"}, "version": {"title": "Version", "type": "string"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Region"}, "location_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Type"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "project": {"$ref": "#/components/schemas/ProjectMeta"}}, "required": ["id", "status", "version", "region", "location_type", "service_code", "robot_set_name", "updated_at", "project"], "title": "RamsDocumentReadinessRow", "type": "object"}, "ReadinessResponse": {"additionalProperties": false, "properties": {"generated_at": {"format": "date-time", "title": "Generated At", "type": "string"}, "team_requests": {"items": {"$ref": "#/components/schemas/TeamRequestReadinessRow"}, "title": "Team Requests", "type": "array"}, "set_requests": {"items": {"$ref": "#/components/schemas/SetRequestReadinessRow"}, "title": "Set Requests", "type": "array"}, "rams_documents": {"items": {"$ref": "#/components/schemas/RamsDocumentReadinessRow"}, "title": "Rams Documents", "type": "array"}}, "required": ["generated_at", "team_requests", "set_requests", "rams_documents"], "title": "ReadinessResponse", "type": "object"}, "SetRequestReadinessRow": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "display_id": {"title": "Display Id", "type": "string"}, "status": {"title": "Status", "type": "string"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "needed_by_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Needed By Date"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}, "ppe_count": {"title": "Ppe Count", "type": "integer"}, "consumables_count": {"title": "Consumables Count", "type": "integer"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "project": {"$ref": "#/components/schemas/ProjectMeta"}}, "required": ["id", "display_id", "status", "robot_set_name", "needed_by_date", "dates_from", "dates_to", "ppe_count", "consumables_count", "updated_at", "project"], "title": "SetRequestReadinessRow", "type": "object"}, "TeamRequestReadinessRow": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "display_id": {"title": "Display Id", "type": "string"}, "status": {"title": "Status", "type": "string"}, "people_count": {"title": "People Count", "type": "integer"}, "slots_count": {"title": "Slots Count", "type": "integer"}, "dates_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates From"}, "dates_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Dates To"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Robot Set Name"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "project": {"$ref": "#/components/schemas/ProjectMeta"}}, "required": ["id", "display_id", "status", "people_count", "slots_count", "dates_from", "dates_to", "robot_set_name", "service_id", "updated_at", "project"], "title": "TeamRequestReadinessRow", "type": "object"}, "UpcomingRotationResponse": {"additionalProperties": false, "description": "One upcoming rotation, mapped for the frontend list.\n\n``status`` is passed through from WMS unchanged (already normalized to\n``pending`` / ``confirmed`` / ``cancelled``); the frontend renders the\n3-state chip and treats anything else as a neutral fallback.", "properties": {"external_id": {"title": "External Id", "type": "string"}, "technician_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Technician Name"}, "first_work_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "First Work Date"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "set_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Set Code"}, "roster_diverged": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Roster Diverged"}}, "required": ["external_id"], "title": "UpcomingRotationResponse", "type": "object"}, "SalesOrder": {"additionalProperties": false, "description": "Schema for sales order.", "properties": {"id": {"description": "NetSuite ID for the sales order", "title": "Id", "type": "integer"}, "name": {"description": "Sales order name", "title": "Name", "type": "string"}, "ns_project_id": {"description": "NetSuite ID for (NS) project", "title": "Ns Project Id", "type": "integer"}, "customer_id": {"description": "NetSuite ID for customer", "title": "Customer Id", "type": "integer"}, "customer_name": {"description": "Customer name", "title": "Customer Name", "type": "string"}, "status_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status name", "title": "Status Name"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for currency", "title": "Currency Id"}, "currency_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency name", "title": "Currency Name"}, "offer_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Offer version", "title": "Offer Version"}, "created_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Sales order transaction date", "title": "Created Date"}, "source_system": {"anyOf": [{"$ref": "#/components/schemas/SalesOrderSourceSystem"}, {"type": "null"}], "description": "Source system for sales order (legacy, ops_hub)"}}, "required": ["id", "name", "ns_project_id", "customer_id", "customer_name"], "title": "SalesOrder", "type": "object"}, "SalesOrderSourceSystem": {"description": "Source system for sales order creation.", "enum": [1, 2], "title": "SalesOrderSourceSystem", "type": "integer"}, "SalesOrderPOST": {"additionalProperties": false, "description": "Schema for sales order POST.", "properties": {"netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Netsuite Customer Id"}, "source_system": {"anyOf": [{"$ref": "#/components/schemas/SalesOrderSourceSystem"}, {"type": "null"}]}}, "title": "SalesOrderPOST", "type": "object"}, "CombinedSalesOrderStatus": {"additionalProperties": false, "description": "Combined sales order creation and sync status schema.", "properties": {"project_id": {"description": "Project ID", "title": "Project Id", "type": "string"}, "creation_status": {"$ref": "#/components/schemas/SalesOrderStatus", "description": "Sales order creation status"}, "sync_status": {"$ref": "#/components/schemas/SalesOrderStatus", "description": "Sales order sync status (only if sales order exists)"}, "invoice_status": {"$ref": "#/components/schemas/SalesOrderStatus", "description": "Invoice creation status (only if invoice creation was triggered)"}}, "required": ["project_id", "creation_status", "sync_status", "invoice_status"], "title": "CombinedSalesOrderStatus", "type": "object"}, "SalesOrderStatus": {"additionalProperties": false, "description": "Sales order status schema - handles both creation and sync operations.", "properties": {"project_id": {"description": "Project ID", "title": "Project Id", "type": "string"}, "record_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Record ID (None during creation, set after)", "title": "Record Id"}, "status": {"allOf": [{"$ref": "#/components/schemas/TaskStatus"}], "default": "inactive", "description": "Operation status"}, "offer_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Offer version", "title": "Offer Version"}, "status_message": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status message", "title": "Status Message"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Operation started at", "title": "Started At"}, "completed_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Operation completed at", "title": "Completed At"}, "progress_percentage": {"default": 0, "description": "Progress percentage (0-100)", "title": "Progress Percentage", "type": "integer"}, "error_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Error code", "title": "Error Code"}}, "required": ["project_id"], "title": "SalesOrderStatus", "type": "object"}, "TaskStatus": {"description": "status enumeration.", "enum": ["ongoing", "completed", "error", "inactive"], "title": "TaskStatus", "type": "string"}, "SalesOrderLineItem": {"additionalProperties": false, "description": "Schema for sales order line item.", "properties": {"id": {"description": "NetSuite internal ID for the sales order line item", "title": "Id", "type": "integer"}, "sales_order_id": {"description": "NetSuite ID for (parent) sales order", "title": "Sales Order Id", "type": "integer"}, "ns_project_id": {"description": "NetSuite ID for (NS) project", "title": "Ns Project Id", "type": "integer"}, "charge_count": {"description": "Number of charges created for this line item", "title": "Charge Count", "type": "integer"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item quantity", "title": "Quantity"}, "rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item rate in SO currency", "title": "Rate"}, "rate_base": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item rate in base/subsidiary currency", "title": "Rate Base"}, "amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item amount", "title": "Amount"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service", "title": "Service Id"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service name", "title": "Service Name"}, "service_unit_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service type", "title": "Service Unit Type Id"}, "service_unit_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service type name", "title": "Service Unit Type Name"}, "service_unit_conversion_rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Conversion rate for service unit type", "title": "Service Unit Conversion Rate"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset", "title": "Asset Id"}, "asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset name", "title": "Asset Name"}, "asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset alt name", "title": "Asset Altname"}, "asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset type", "title": "Asset Type Id"}, "asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type name", "title": "Asset Type Name"}, "line_is_disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Line item disabled flag", "title": "Line Is Disabled"}, "asset_is_disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Asset disabled flag", "title": "Asset Is Disabled"}, "persistent_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Persistent ID", "title": "Persistent Id"}, "parent_asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for parent asset", "title": "Parent Asset Id"}, "parent_asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Parent asset name", "title": "Parent Asset Name"}, "parent_asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Parent asset alt name", "title": "Parent Asset Altname"}, "parent_asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for parent asset type", "title": "Parent Asset Type Id"}, "parent_asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Parent Asset type name", "title": "Parent Asset Type Name"}}, "required": ["id", "sales_order_id", "ns_project_id", "charge_count"], "title": "SalesOrderLineItem", "type": "object"}, "ServiceRate": {"additionalProperties": false, "description": "Service and rate mapping schema.", "properties": {"service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service", "title": "Service Id"}, "service_name": {"description": "Service name", "title": "Service Name", "type": "string"}, "rate": {"description": "Service rate", "title": "Rate", "type": "number"}, "is_disabled": {"default": false, "description": "True when underlying line-item/asset is disabled", "title": "Is Disabled", "type": "boolean"}}, "required": ["service_name", "rate"], "title": "ServiceRate", "type": "object"}, "SalesOrderLineItemPart": {"additionalProperties": false, "description": "Schema for sales order line item.", "properties": {"id": {"description": "NetSuite internal ID for the sales order line item", "title": "Id", "type": "integer"}, "sales_order_id": {"description": "NetSuite ID for (parent) sales order", "title": "Sales Order Id", "type": "integer"}, "ns_project_id": {"description": "NetSuite ID for (NS) project", "title": "Ns Project Id", "type": "integer"}, "charge_count": {"description": "Number of charges created for this line item", "title": "Charge Count", "type": "integer"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item quantity", "title": "Quantity"}, "rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item rate in SO currency", "title": "Rate"}, "rate_base": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item rate in base/subsidiary currency", "title": "Rate Base"}, "amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item amount", "title": "Amount"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service", "title": "Service Id"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service name", "title": "Service Name"}, "service_unit_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service type", "title": "Service Unit Type Id"}, "service_unit_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service type name", "title": "Service Unit Type Name"}, "service_unit_conversion_rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Conversion rate for service unit type", "title": "Service Unit Conversion Rate"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset", "title": "Asset Id"}, "asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset name", "title": "Asset Name"}, "asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset alt name", "title": "Asset Altname"}, "asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset type", "title": "Asset Type Id"}, "asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type name", "title": "Asset Type Name"}, "line_is_disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Line item disabled flag", "title": "Line Is Disabled"}, "asset_is_disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Asset disabled flag", "title": "Asset Is Disabled"}, "persistent_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Persistent ID", "title": "Persistent Id"}}, "required": ["id", "sales_order_id", "ns_project_id", "charge_count"], "title": "SalesOrderLineItemPart", "type": "object"}, "SalesOrderLineItemTLNode": {"additionalProperties": false, "description": "Sales Order Line Item top-level node in tree.", "properties": {"id": {"description": "NetSuite internal ID for the sales order line item", "title": "Id", "type": "integer"}, "sales_order_id": {"description": "NetSuite ID for (parent) sales order", "title": "Sales Order Id", "type": "integer"}, "ns_project_id": {"description": "NetSuite ID for (NS) project", "title": "Ns Project Id", "type": "integer"}, "charge_count": {"description": "Number of charges created for this line item", "title": "Charge Count", "type": "integer"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item quantity", "title": "Quantity"}, "rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item rate in SO currency", "title": "Rate"}, "rate_base": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item rate in base/subsidiary currency", "title": "Rate Base"}, "amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Line item amount", "title": "Amount"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service", "title": "Service Id"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service name", "title": "Service Name"}, "service_unit_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service type", "title": "Service Unit Type Id"}, "service_unit_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service type name", "title": "Service Unit Type Name"}, "service_unit_conversion_rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Conversion rate for service unit type", "title": "Service Unit Conversion Rate"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset", "title": "Asset Id"}, "asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset name", "title": "Asset Name"}, "asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset alt name", "title": "Asset Altname"}, "asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset type", "title": "Asset Type Id"}, "asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type name", "title": "Asset Type Name"}, "line_is_disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Line item disabled flag", "title": "Line Is Disabled"}, "asset_is_disabled": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Asset disabled flag", "title": "Asset Is Disabled"}, "persistent_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Persistent ID", "title": "Persistent Id"}, "blades": {"items": {"$ref": "#/components/schemas/SalesOrderLineItemPart"}, "title": "Blades", "type": "array"}}, "required": ["id", "sales_order_id", "ns_project_id", "charge_count", "blades"], "title": "SalesOrderLineItemTLNode", "type": "object"}, "Charge": {"additionalProperties": false, "description": "Schema for charge.", "properties": {"id": {"description": "NetSuite ID for charge", "title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Charge name", "title": "Name"}, "charge_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Charge date", "title": "Charge Date"}, "ns_project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for (NS) project", "title": "Ns Project Id"}, "ns_project_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Project name", "title": "Ns Project Name"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for sales order", "title": "Sales Order Id"}, "sales_order_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order name", "title": "Sales Order Name"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Dispatch service-order ID", "title": "Service Order Id"}, "sales_order_line_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for sales order line item", "title": "Sales Order Line Item Id"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Price", "title": "Price"}, "status_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for status", "title": "Status Id"}, "status_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status name", "title": "Status Name"}, "invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for invoice", "title": "Invoice Id"}, "invoice_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Invoice date", "title": "Invoice Date"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service", "title": "Service Id"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service name", "title": "Service Name"}, "service_unit_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service unit type", "title": "Service Unit Type Id"}, "service_unit_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service unit type name", "title": "Service Unit Type Name"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset", "title": "Asset Id"}, "asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset name", "title": "Asset Name"}, "asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset alt name", "title": "Asset Altname"}, "asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset type", "title": "Asset Type Id"}, "asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type name", "title": "Asset Type Name"}, "parent_asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for parent asset", "title": "Parent Asset Id"}, "parent_asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Parent asset name", "title": "Parent Asset Name"}, "parent_asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Parent asset alt name", "title": "Parent Asset Altname"}, "parent_asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for parent asset type", "title": "Parent Asset Type Id"}, "parent_asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Parent asset type name", "title": "Parent Asset Type Name"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for robot set", "title": "Robot Set Id"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of the robot set", "title": "Robot Set Name"}, "total": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total amount", "title": "Total"}, "service_activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service activity description (300 char limit)", "title": "Service Activity Description"}, "service_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Idempotency ID for auto-synced idle charges: a Platform service activity ID or a core.Delay ID, depending on source", "title": "Service Activity Id"}, "corrects_charge_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID of the charge this charge corrects", "title": "Corrects Charge Id"}, "invoice_status_name": {"anyOf": [{"$ref": "#/components/schemas/InvoiceStatus"}, {"type": "null"}], "description": "Status of invoice"}, "is_editable": {"description": "Only editable if status is DRAFT", "readOnly": true, "title": "Is Editable", "type": "boolean"}, "doc_sent_status": {"$ref": "#/components/schemas/InvoiceSentStatus", "description": "Combined invoice sent status (Final/Draft/Unsent)", "readOnly": true}}, "required": ["id", "is_editable", "doc_sent_status"], "title": "Charge", "type": "object"}, "InvoiceSentStatus": {"description": "Invoice sent status enum.\n\nIndicates whether a draft or final invoice document has been sent to the customer.", "enum": ["Unsent", "Draft", "Final"], "title": "InvoiceSentStatus", "type": "string"}, "InvoiceStatus": {"description": "Invoice status enum from NetSuite.\n\nThese statuses come from NetSuite's transaction status table for invoice records.\nValues queried from transactionstatus table where trantype = 'CustInvc'.", "enum": ["Open", "Paid In Full", "Pending Approval", "Rejected", "Undefined", "Voided"], "title": "InvoiceStatus", "type": "string"}, "ChargeBulkPATCHItem": {"additionalProperties": false, "description": "Schema for bulk PATCH charge item.", "properties": {"id": {"description": "Charge ID", "title": "Id", "type": "integer"}, "status": {"$ref": "#/components/schemas/ChargeStatusName", "description": "New status for the charge"}}, "required": ["id", "status"], "title": "ChargeBulkPATCHItem", "type": "object"}, "ChargeStatusName": {"description": "Charge status names matching NetSuite status IDs.", "enum": ["DRAFT", "APPROVED"], "title": "ChargeStatusName", "type": "string"}, "ChargeBulkDELETE": {"additionalProperties": false, "description": "Schema for bulk DELETE charges.", "properties": {"ids": {"description": "List of charge IDs to delete", "items": {"type": "integer"}, "title": "Ids", "type": "array"}}, "required": ["ids"], "title": "ChargeBulkDELETE", "type": "object"}, "EmailSendLogChargeResponse": {"additionalProperties": false, "description": "A single charge included in a sent email, for the expanded row detail.", "properties": {"id": {"title": "Id", "type": "integer"}, "charge_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Charge Date"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Name"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Quantity"}, "price": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Price"}, "total": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Total"}}, "required": ["id", "charge_date", "service_name", "quantity", "price", "total"], "title": "EmailSendLogChargeResponse", "type": "object"}, "EmailSendLogResponse": {"additionalProperties": false, "description": "A single sent-email record for a project's accounting history.", "properties": {"id": {"format": "uuid", "title": "Id", "type": "string"}, "sent_at": {"title": "Sent At", "type": "string"}, "subject": {"title": "Subject", "type": "string"}, "status": {"title": "Status", "type": "string"}, "status_changed_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status Changed At"}, "template_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Template Name"}, "recipients_to": {"items": {"type": "string"}, "title": "Recipients To", "type": "array"}, "recipients_cc": {"items": {"type": "string"}, "title": "Recipients Cc", "type": "array"}, "recipients_bcc": {"items": {"type": "string"}, "title": "Recipients Bcc", "type": "array"}, "charges": {"items": {"$ref": "#/components/schemas/EmailSendLogChargeResponse"}, "title": "Charges", "type": "array"}}, "required": ["id", "sent_at", "subject", "status", "status_changed_at", "template_name", "recipients_to", "recipients_cc", "recipients_bcc", "charges"], "title": "EmailSendLogResponse", "type": "object"}, "ChargeStatusSummary": {"additionalProperties": false, "description": "All charges in one status on a sales order, aggregated.", "properties": {"status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NetSuite charge status; None when the charge has no status", "title": "Status"}, "count": {"default": 0, "description": "Number of charges in this status", "title": "Count", "type": "integer"}, "total_amount": {"default": 0.0, "description": "Sum of charge amounts", "title": "Total Amount", "type": "number"}}, "title": "ChargeStatusSummary", "type": "object"}, "ChargeSummary": {"additionalProperties": false, "description": "Pre-aggregated charge totals for a sales order, computed from local DB.", "properties": {"total_amount": {"description": "Sum of all charges", "title": "Total Amount", "type": "number"}, "invoiced_amount": {"default": 0.0, "description": "Sum of charges linked to a sales invoice", "title": "Invoiced Amount", "type": "number"}, "acc_amount": {"description": "Sum of ACC / ACC-RAT charges", "title": "Acc Amount", "type": "number"}, "mob_amount": {"description": "Sum of MOB / MOB-RAT charges", "title": "Mob Amount", "type": "number"}, "idle_day_amount": {"description": "Sum of IDLE-DAY / IDLE-DAY-RAT charges", "title": "Idle Day Amount", "type": "number"}, "idle_hour_amount": {"description": "Sum of IDLE-HOUR / IDLE-HOUR-RAT charges", "title": "Idle Hour Amount", "type": "number"}, "groups": {"description": "Charges grouped by charge type, largest sum first", "items": {"$ref": "#/components/schemas/ChargeTypeSummary"}, "title": "Groups", "type": "array"}, "statuses": {"description": "Charges grouped by status, largest sum first", "items": {"$ref": "#/components/schemas/ChargeStatusSummary"}, "title": "Statuses", "type": "array"}}, "required": ["total_amount", "acc_amount", "mob_amount", "idle_day_amount", "idle_hour_amount"], "title": "ChargeSummary", "type": "object"}, "ChargeTypeSummary": {"additionalProperties": false, "description": "All charges of one charge type (service) on a sales order, aggregated.", "properties": {"service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code (charge type); None when the charge has no service", "title": "Service Code"}, "count": {"default": 0, "description": "Number of charges of this type", "title": "Count", "type": "integer"}, "total_amount": {"default": 0.0, "description": "Sum of charge amounts", "title": "Total Amount", "type": "number"}, "invoiced_count": {"default": 0, "description": "How many of these charges are linked to a sales invoice", "title": "Invoiced Count", "type": "integer"}, "invoiced_amount": {"default": 0.0, "description": "Sum of amounts of the invoiced charges", "title": "Invoiced Amount", "type": "number"}}, "title": "ChargeTypeSummary", "type": "object"}, "ChargePOST": {"additionalProperties": false, "description": "Schema for POST charge.", "properties": {"service_id": {"description": "NetSuite ID for service", "title": "Service Id", "type": "integer"}, "quantity": {"description": "Quantity", "title": "Quantity", "type": "number"}, "price": {"description": "Price (i.e. rate)", "title": "Price", "type": "number"}, "charge_date": {"description": "Charge date", "format": "date", "title": "Charge Date", "type": "string"}, "total": {"description": "Total amount (mandatory)", "title": "Total", "type": "number"}, "service_unit_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service unit type", "title": "Service Unit Type Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Dispatch service-order ID", "title": "Service Order Id"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset", "title": "Asset Id"}, "asset_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "NetSuite IDs for assets; when provided, backend creates one charge per asset", "title": "Asset Ids"}, "asset_service_order_pairs": {"anyOf": [{"items": {"maxItems": 2, "minItems": 2, "prefixItems": [{"type": "integer"}, {"type": "integer"}], "type": "array"}, "type": "array"}, {"type": "null"}], "description": "Per-asset service-order pairs in format [(asset_id, service_order_id), ...]. When provided, backend creates one charge per pair.", "title": "Asset Service Order Pairs"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for robot set", "title": "Robot Set Id"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ChargeStatusName"}, {"type": "null"}], "description": "Charge status (APPROVED, DRAFT). Defaults to DRAFT if not provided."}, "service_activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service activity description (300 char limit)", "title": "Service Activity Description"}, "service_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Idempotency ID for auto-synced idle charges (auto-created charges only): a Platform service activity ID or a core.Delay ID, depending on source", "title": "Service Activity Id"}, "delay_ids": {"description": "Delay IDs to link to this charge (local only, not sent to NS)", "items": {"type": "integer"}, "title": "Delay Ids", "type": "array"}, "corrects_charge_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of the charge this charge corrects. When set, quantity/price/total are derived server-side as the exact negation of the referenced charge.", "title": "Corrects Charge Id"}}, "required": ["service_id", "quantity", "price", "charge_date", "total"], "title": "ChargePOST", "type": "object"}, "ChargePATCH": {"additionalProperties": false, "description": "Schema for PATCH charge.", "properties": {"quantity": {"title": "Quantity", "type": "number"}, "charge_date": {"format": "date", "title": "Charge Date", "type": "string"}, "robot_set_id": {"title": "Robot Set Id", "type": "integer"}, "status": {"anyOf": [{"$ref": "#/components/schemas/ChargeStatusName"}, {"type": "null"}]}, "service_activity_description": {"anyOf": [{"maxLength": 300, "type": "string"}, {"type": "null"}], "description": "Service activity description / idle reason (max 300 chars)", "title": "Service Activity Description"}}, "title": "ChargePATCH", "type": "object"}, "ChargeBulkApproveResponse": {"additionalProperties": false, "description": "Response for bulk-approve charges.", "properties": {"approved_ids": {"description": "IDs of charges that were approved", "items": {"type": "integer"}, "title": "Approved Ids", "type": "array"}}, "required": ["approved_ids"], "title": "ChargeBulkApproveResponse", "type": "object"}, "ChargeBulkApprove": {"additionalProperties": false, "description": "Input for bulk-approving charges.", "properties": {"ids": {"description": "List of charge IDs to approve", "items": {"type": "integer"}, "minItems": 1, "title": "Ids", "type": "array"}}, "required": ["ids"], "title": "ChargeBulkApprove", "type": "object"}, "AccountingInvoice": {"additionalProperties": false, "description": "Schema for invoice response with linked charges.", "properties": {"id": {"description": "NetSuite invoice ID", "title": "Id", "type": "integer"}, "sales_order_id": {"description": "NetSuite sales order ID", "title": "Sales Order Id", "type": "integer"}, "transaction_number": {"description": "Invoice transaction number", "title": "Transaction Number", "type": "string"}, "status": {"description": "Invoice status", "title": "Status", "type": "string"}, "total_amount": {"description": "Total invoice amount", "title": "Total Amount", "type": "number"}, "created_date": {"description": "Date invoice was created", "format": "date", "title": "Created Date", "type": "string"}, "posting_period": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Posting period name (Service Period)", "title": "Posting Period"}, "currency_id": {"description": "NetSuite currency ID", "title": "Currency Id", "type": "integer"}, "currency_name": {"description": "Currency name", "title": "Currency Name", "type": "string"}, "charges": {"description": "Charges linked to this invoice", "items": {"$ref": "#/components/schemas/AccountingInvoiceCharge"}, "title": "Charges", "type": "array"}, "invoice_draft_sent": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Is draft invoice sent (internal use only)", "title": "Invoice Draft Sent"}, "invoice_final_sent": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Is final invoice sent (internal use only)", "title": "Invoice Final Sent"}}, "required": ["id", "sales_order_id", "transaction_number", "status", "total_amount", "created_date", "currency_id", "currency_name"], "title": "AccountingInvoice", "type": "object"}, "AccountingInvoiceCharge": {"additionalProperties": false, "description": "Schema for charge linked to an invoice.", "properties": {"charge_id": {"description": "NetSuite charge ID", "title": "Charge Id", "type": "integer"}, "charge_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Charge date", "title": "Charge Date"}, "service_name": {"description": "Service name", "title": "Service Name", "type": "string"}, "service_unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service unit type", "title": "Service Unit Type"}, "quantity": {"description": "Charge quantity", "title": "Quantity", "type": "number"}, "price": {"description": "Charge price", "title": "Price", "type": "number"}, "total": {"description": "Charge total amount", "title": "Total", "type": "number"}, "failed": {"default": false, "description": "Whether this charge failed to be included in the invoice", "title": "Failed", "type": "boolean"}}, "required": ["charge_id", "service_name", "quantity", "price", "total"], "title": "AccountingInvoiceCharge", "type": "object"}, "CreateInvoiceResponse": {"additionalProperties": true, "description": "Schema for API response after invoice creation flow.", "properties": {"success": {"description": "Indicates if the invoice creation was successful.", "title": "Success", "type": "boolean"}, "invoice_ids": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "NetSuite invoice IDs linked to the charges.", "title": "Invoice Ids"}, "queue_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Queue record ID.", "title": "Queue Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Queue status text.", "title": "Status"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Error code from NetSuite.", "title": "Error"}, "message": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Error message from NetSuite.", "title": "Message"}}, "required": ["success"], "title": "CreateInvoiceResponse", "type": "object"}, "CreateSalesOrderInvoicePOST": {"additionalProperties": false, "description": "Schema for creating an invoice from a sales order.", "properties": {"charge_ids": {"description": "List of NetSuite Charge IDs to include in the invoice", "items": {"type": "integer"}, "title": "Charge Ids", "type": "array"}, "subsidiary_id": {"description": "NetSuite subsidiary ID", "title": "Subsidiary Id", "type": "integer"}}, "required": ["charge_ids", "subsidiary_id"], "title": "CreateSalesOrderInvoicePOST", "type": "object"}, "PatchStrValue": {"additionalProperties": false, "description": "Patch string value.", "properties": {"old": {"title": "Old", "type": "string"}, "new": {"title": "New", "type": "string"}}, "required": ["old", "new"], "title": "PatchStrValue", "type": "object"}, "AssetPatchGET": {"additionalProperties": false, "description": "Asset patch GET", "properties": {"patch_id": {"title": "Patch Id", "type": "string"}, "patch": {"additionalProperties": {"$ref": "#/components/schemas/PatchStrValue"}, "title": "Patch", "type": "object"}}, "required": ["patch_id", "patch"], "title": "AssetPatchGET", "type": "object"}, "AssetPatchPATCH": {"additionalProperties": false, "description": "Asset patch PATCH", "properties": {"patch_id": {"title": "Patch Id", "type": "string"}}, "required": ["patch_id"], "title": "AssetPatchPATCH", "type": "object"}, "IdleHourSubCategoryOption": {"additionalProperties": false, "description": "An available sub-category option for idle-hour time windows.", "properties": {"category": {"description": "Parent delay category", "title": "Category", "type": "string"}, "value": {"description": "Sub-category value (delay type label)", "title": "Value", "type": "string"}}, "required": ["category", "value"], "title": "IdleHourSubCategoryOption", "type": "object"}, "IdleHourTimeWindow": {"additionalProperties": false, "description": "Schema for an idle-hour delay time window.", "properties": {"start_time": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Start time in HH:MM format", "title": "Start Time"}, "end_time": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "End time in HH:MM format", "title": "End Time"}, "category": {"description": "Delay category", "title": "Category", "type": "string"}, "sub_category": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Delay sub-category (delay type code or description)", "title": "Sub Category"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Delay comment or activity type name", "title": "Description"}, "counts_towards_chargeable": {"description": "Whether this delay counts towards chargeable idle hours", "title": "Counts Towards Chargeable", "type": "boolean"}}, "required": ["category", "counts_towards_chargeable"], "title": "IdleHourTimeWindow", "type": "object"}, "IdleHourTimeWindowsResponse": {"additionalProperties": false, "description": "Response wrapper for idle-hour time windows.", "properties": {"windows": {"items": {"$ref": "#/components/schemas/IdleHourTimeWindow"}, "title": "Windows", "type": "array"}, "sub_categories": {"description": "Available sub-category options grouped by category", "items": {"$ref": "#/components/schemas/IdleHourSubCategoryOption"}, "title": "Sub Categories", "type": "array"}}, "title": "IdleHourTimeWindowsResponse", "type": "object"}, "SyncDelayChargesError": {"additionalProperties": false, "description": "Error details for a failed delay charge sync.", "properties": {"service_activity_id": {"description": "ID of the delay (or Platform service activity) that failed to sync", "title": "Service Activity Id", "type": "integer"}, "error": {"description": "Error message", "title": "Error", "type": "string"}}, "required": ["service_activity_id", "error"], "title": "SyncDelayChargesError", "type": "object"}, "SyncDelayChargesResponse": {"additionalProperties": false, "description": "Response schema for sync delay charges operation.", "properties": {"created_count": {"description": "Number of charges created", "title": "Created Count", "type": "integer"}, "skipped_existing_count": {"description": "Number of delays skipped (already have charges)", "title": "Skipped Existing Count", "type": "integer"}, "skipped_no_match_count": {"description": "Number of delays skipped (no matching line item)", "title": "Skipped No Match Count", "type": "integer"}, "error_count": {"description": "Number of errors encountered", "title": "Error Count", "type": "integer"}, "created_charges": {"description": "List of created charges", "items": {"$ref": "#/components/schemas/Charge"}, "title": "Created Charges", "type": "array"}, "skipped_existing_ids": {"description": "Service activity IDs that were skipped (already exist)", "items": {"type": "integer"}, "title": "Skipped Existing Ids", "type": "array"}, "skipped_no_match_ids": {"description": "Service activity IDs with no matching line item", "items": {"type": "integer"}, "title": "Skipped No Match Ids", "type": "array"}, "errors": {"description": "List of errors", "items": {"$ref": "#/components/schemas/SyncDelayChargesError"}, "title": "Errors", "type": "array"}}, "required": ["created_count", "skipped_existing_count", "skipped_no_match_count", "error_count", "created_charges", "skipped_existing_ids", "skipped_no_match_ids", "errors"], "title": "SyncDelayChargesResponse", "type": "object"}, "AccountingComment": {"additionalProperties": false, "description": "Schema for accounting comment response.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"format": "uuid", "title": "Project Id", "type": "string"}, "date": {"format": "date", "title": "Date", "type": "string"}, "text": {"title": "Text", "type": "string"}, "is_completed": {"title": "Is Completed", "type": "boolean"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "created_by_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Created By Id"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}}, "required": ["id", "project_id", "date", "text", "is_completed", "created_at", "updated_at"], "title": "AccountingComment", "type": "object"}, "AccountingCommentPOST": {"additionalProperties": false, "description": "Schema for creating an accounting comment.", "properties": {"date": {"format": "date", "title": "Date", "type": "string"}, "text": {"title": "Text", "type": "string"}}, "required": ["date", "text"], "title": "AccountingCommentPOST", "type": "object"}, "AccountingCommentPATCH": {"additionalProperties": false, "description": "Schema for updating an accounting comment.", "properties": {"is_completed": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Completed"}, "text": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Text"}}, "title": "AccountingCommentPATCH", "type": "object"}, "SuggestionDecisionSchema": {"additionalProperties": false, "description": "Schema for suggestion decision response.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"format": "uuid", "title": "Project Id", "type": "string"}, "date": {"format": "date", "title": "Date", "type": "string"}, "set_name": {"title": "Set Name", "type": "string"}, "label": {"title": "Label", "type": "string"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Asset Id"}, "decision": {"title": "Decision", "type": "string"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Created By Name"}}, "required": ["id", "project_id", "date", "set_name", "label", "decision", "created_at"], "title": "SuggestionDecisionSchema", "type": "object"}, "SuggestionDecisionPOST": {"additionalProperties": false, "description": "Schema for creating/updating a suggestion decision.", "properties": {"date": {"format": "date", "title": "Date", "type": "string"}, "set_name": {"title": "Set Name", "type": "string"}, "label": {"title": "Label", "type": "string"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Asset Id"}, "decision": {"title": "Decision", "type": "string"}}, "required": ["date", "set_name", "label", "decision"], "title": "SuggestionDecisionPOST", "type": "object"}, "SuggestionDecisionDELETE": {"additionalProperties": false, "description": "Schema for deleting a suggestion decision.", "properties": {"date": {"format": "date", "title": "Date", "type": "string"}, "set_name": {"title": "Set Name", "type": "string"}, "label": {"title": "Label", "type": "string"}, "asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Asset Id"}}, "required": ["date", "set_name", "label"], "title": "SuggestionDecisionDELETE", "type": "object"}, "ActivitySegment": {"additionalProperties": false, "description": "A time segment for the activity timeline.", "properties": {"start_dt": {"description": "ISO datetime start", "title": "Start Dt", "type": "string"}, "end_dt": {"description": "ISO datetime end", "title": "End Dt", "type": "string"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name if available", "title": "Turbine Name"}, "segment_type": {"description": "Segment type: work, info, aerones, customer, weather, or other", "title": "Segment Type", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Activity description or delay description", "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Activity status (for work segments)", "title": "Status"}}, "required": ["start_dt", "end_dt", "segment_type"], "title": "ActivitySegment", "type": "object"}, "ExpectedChargeDetail": {"additionalProperties": false, "description": "Detail for a single expected/approximate charge.", "properties": {"label": {"description": "Charge label, e.g. ACC, IDLE-HOUR", "title": "Label", "type": "string"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Resolved NetSuite service ID", "title": "Service Id"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Resolved service name from line item", "title": "Service Name"}, "rate": {"description": "Unit rate from sales order line item", "title": "Rate", "type": "number"}, "quantity": {"description": "Expected quantity (1 for ACC/IDLE-DAY, idle hours for IDLE-HOUR)", "title": "Quantity", "type": "number"}, "total": {"description": "rate * quantity", "title": "Total", "type": "number"}}, "required": ["label", "rate", "quantity", "total"], "title": "ExpectedChargeDetail", "type": "object"}, "TeamWorkloadDay": {"additionalProperties": false, "description": "Schema for daily team workload summary.", "properties": {"date": {"description": "Calendar date for the workload summary", "format": "date", "title": "Date", "type": "string"}, "total_set_count": {"description": "Total number of sets assigned to the project", "title": "Total Set Count", "type": "integer"}, "worked_set_count": {"description": "Number of sets with direct minutes >= 60", "title": "Worked Set Count", "type": "integer"}, "worked_set_percentage": {"description": "Percentage of assigned sets that worked (0-100)", "title": "Worked Set Percentage", "type": "number"}, "worked_set_names": {"description": "Set names that worked on the day", "items": {"type": "string"}, "title": "Worked Set Names", "type": "array"}, "not_worked_set_names": {"description": "Set names assigned but not worked on the day", "items": {"type": "string"}, "title": "Not Worked Set Names", "type": "array"}, "set_statuses": {"description": "Per-set workload and idle status details", "items": {"$ref": "#/components/schemas/TeamWorkloadSetStatus"}, "title": "Set Statuses", "type": "array"}}, "required": ["date", "total_set_count", "worked_set_count", "worked_set_percentage", "worked_set_names", "not_worked_set_names", "set_statuses"], "title": "TeamWorkloadDay", "type": "object"}, "TeamWorkloadSetStatus": {"additionalProperties": false, "description": "Schema for set workload status details.", "properties": {"set_name": {"title": "Set Name", "type": "string"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "OpsHub core.RobotSet id, for routes keyed by the local id.", "title": "Robot Set Id"}, "ns_robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite id of the robot set. Lets the client join charges to this set by id instead of reconciling the two systems' set names.", "title": "Ns Robot Set Id"}, "workorder_service_codes": {"description": "Service codes from workorders for the day", "items": {"type": "string"}, "title": "Workorder Service Codes", "type": "array"}, "direct_minutes": {"description": "Direct work minutes for the set", "title": "Direct Minutes", "type": "number"}, "total_delay_minutes": {"description": "Total delay minutes for the set", "title": "Total Delay Minutes", "type": "number"}, "aerones_delay_minutes": {"description": "Aerones delay minutes for the set", "title": "Aerones Delay Minutes", "type": "number"}, "customer_delay_minutes": {"description": "Customer delay minutes for the set", "title": "Customer Delay Minutes", "type": "number"}, "weather_delay_minutes": {"description": "Weather delay minutes for the set", "title": "Weather Delay Minutes", "type": "number"}, "other_delay_minutes": {"description": "Other delay minutes for the set", "title": "Other Delay Minutes", "type": "number"}, "worked": {"description": "True if direct minutes meet or exceed the worked threshold", "title": "Worked", "type": "boolean"}, "aerones_idle_day": {"description": "True if Aerones delay dominates the day with low direct work", "title": "Aerones Idle Day", "type": "boolean"}, "customer_idle_day": {"description": "True if customer delay dominates the day with low direct work", "title": "Customer Idle Day", "type": "boolean"}, "weather_idle_day": {"description": "True if weather delay dominates the day with low direct work", "title": "Weather Idle Day", "type": "boolean"}, "other_idle_day": {"description": "True if other delay dominates the day with low direct work", "title": "Other Idle Day", "type": "boolean"}, "had_idle": {"description": "True if customer/other/weather delays reached idle threshold on a worked day", "title": "Had Idle", "type": "boolean"}, "no_activity": {"default": false, "description": "True if set has a workorder assigned but no direct or delay activity for the day", "title": "No Activity", "type": "boolean"}, "day_off": {"default": false, "description": "True if set has no workorder assigned and no direct or delay activity for the day", "title": "Day Off", "type": "boolean"}, "expected_charges": {"description": "Expected charge labels based on set status and available services", "items": {"type": "string"}, "title": "Expected Charges", "type": "array"}, "suggested_charges": {"description": "Suggested charges with prefilled service and asset details", "items": {"$ref": "#/components/schemas/TeamWorkloadSuggestedCharge"}, "title": "Suggested Charges", "type": "array"}, "expected_charge_details": {"description": "Expected charges with resolved monetary amounts", "items": {"$ref": "#/components/schemas/ExpectedChargeDetail"}, "title": "Expected Charge Details", "type": "array"}, "approximate_revenue": {"default": 0.0, "description": "Sum of expected charge totals (approximate revenue for this set-day)", "title": "Approximate Revenue", "type": "number"}, "idle_delay_ids": {"description": "IDs of delays that contributed to idle minutes for this set-day", "items": {"type": "integer"}, "title": "Idle Delay Ids", "type": "array"}, "activity_segments": {"description": "Individual activity/delay time segments for timeline display", "items": {"$ref": "#/components/schemas/ActivitySegment"}, "title": "Activity Segments", "type": "array"}}, "required": ["set_name", "direct_minutes", "total_delay_minutes", "aerones_delay_minutes", "customer_delay_minutes", "weather_delay_minutes", "other_delay_minutes", "worked", "aerones_idle_day", "customer_idle_day", "weather_idle_day", "other_idle_day", "had_idle"], "title": "TeamWorkloadSetStatus", "type": "object"}, "TeamWorkloadSuggestedCharge": {"additionalProperties": false, "description": "Schema for suggested charge candidate with prefill details.", "properties": {"label": {"description": "Suggested charge label displayed in UI", "title": "Label", "type": "string"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service", "title": "Service Id"}, "service_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service name", "title": "Service Name"}, "service_unit_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for service unit type", "title": "Service Unit Type Id"}, "service_unit_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service unit type name", "title": "Service Unit Type Name"}, "rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Suggested service rate", "title": "Rate"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Suggested quantity \u2014 direct work hours for -RAT services, otherwise unset (frontend falls back to 1)", "title": "Quantity"}, "primary_asset_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Preferred asset ID for charge prefill", "title": "Primary Asset Id"}, "assets": {"description": "Asset options related to the suggested service", "items": {"$ref": "#/components/schemas/TeamWorkloadSuggestedChargeAsset"}, "title": "Assets", "type": "array"}}, "required": ["label"], "title": "TeamWorkloadSuggestedCharge", "type": "object"}, "TeamWorkloadSuggestedChargeAsset": {"additionalProperties": false, "description": "Schema for suggested charge asset candidate.", "properties": {"asset_id": {"description": "NetSuite ID for asset", "title": "Asset Id", "type": "integer"}, "service_order_id": {"description": "Dispatch service-order ID for this asset suggestion", "title": "Service Order Id", "type": "integer"}, "asset_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset name", "title": "Asset Name"}, "asset_altname": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset alt name", "title": "Asset Altname"}, "asset_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID for asset type", "title": "Asset Type Id"}, "asset_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type name", "title": "Asset Type Name"}}, "required": ["asset_id", "service_order_id"], "title": "TeamWorkloadSuggestedChargeAsset", "type": "object"}, "DelayItem": {"additionalProperties": false, "description": "A single delay for a robot set on a given day.", "properties": {"delay_id": {"title": "Delay Id", "type": "integer"}, "type_code": {"title": "Type Code", "type": "string"}, "type_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type Description"}, "category_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Category Code"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "duration_minutes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Minutes"}}, "required": ["delay_id", "type_code"], "title": "DelayItem", "type": "object"}, "ChargedRevenueResponse": {"additionalProperties": false, "description": "Response schema for charged revenue aggregation.", "properties": {"charged_revenue": {"description": "Total charged revenue from approved charges", "title": "Charged Revenue", "type": "number"}}, "required": ["charged_revenue"], "title": "ChargedRevenueResponse", "type": "object"}, "NSServiceCountry": {"description": "NetSuite service country segment.", "properties": {"id": {"description": "NetSuite ID", "title": "Id", "type": "integer"}, "name": {"description": "Country name", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "NSServiceCountry", "type": "object"}, "TurbineProgressAsset": {"additionalProperties": false, "description": "A turbine in the turbines charge progress panel.", "properties": {"id": {"description": "Turbine ID (local DB)", "title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Turbine name", "title": "Name"}, "type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type name (WTG or Blade)", "title": "Type Name"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade position on the turbine (A/B/C); None for turbines and non-blade components", "title": "Position"}, "parent_turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Owning turbine ID for a component asset; None for turbines", "title": "Parent Turbine Id"}, "parent_turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Owning turbine name for a component asset; None for turbines", "title": "Parent Turbine Name"}, "parent_turbine_is_virtual": {"default": false, "description": "True when the owning turbine is a virtual holder (a port/warehouse with no manufacturer turbine model) rather than a physical WTG", "title": "Parent Turbine Is Virtual", "type": "boolean"}, "has_chargeable_work": {"default": false, "description": "The asset has a billable service-order line that is field-completed or completed, and no charge on it under any of the project's sales orders", "title": "Has Chargeable Work", "type": "boolean"}, "has_completed_sol": {"default": false, "description": "A service-order line for this asset is field-completed or completed, regardless of billability or charges", "title": "Has Completed Sol", "type": "boolean"}, "charged_on_other_sales_order": {"default": false, "description": "The asset has no charge under this sales order but is charged under another sales order of the project", "title": "Charged On Other Sales Order", "type": "boolean"}, "all_sols_cancelled": {"default": false, "description": "The asset has service-order lines and every one of them is cancelled \u2014 no active or delivered work remains", "title": "All Sols Cancelled", "type": "boolean"}, "has_active_sol": {"default": false, "description": "A service-order line for this asset is not started or in progress \u2014 work is still planned or underway", "title": "Has Active Sol", "type": "boolean"}, "charge_dates": {"description": "Dates of charges", "items": {"format": "date", "type": "string"}, "title": "Charge Dates", "type": "array"}, "charge_groups": {"description": "Charges grouped by charge type", "items": {"$ref": "#/components/schemas/TurbineProgressChargeGroup"}, "title": "Charge Groups", "type": "array"}}, "required": ["id"], "title": "TurbineProgressAsset", "type": "object"}, "TurbineProgressCharge": {"additionalProperties": false, "description": "One charge inside a charge-type group on an asset.", "properties": {"charge_date": {"description": "Date the charge was made for", "format": "date", "title": "Charge Date", "type": "string"}, "created_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full name of the OpsHub user who created the charge; None for NetSuite-synced charges", "title": "Created By Name"}}, "required": ["charge_date"], "title": "TurbineProgressCharge", "type": "object"}, "TurbineProgressChargeGroup": {"additionalProperties": false, "description": "One asset's charges of a single charge type (service), aggregated.", "properties": {"service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code (charge type); None when the charge has no service", "title": "Service Code"}, "count": {"default": 0, "description": "Number of charges of this type", "title": "Count", "type": "integer"}, "total_amount": {"default": 0.0, "description": "Sum of charge amounts", "title": "Total Amount", "type": "number"}, "invoiced_count": {"default": 0, "description": "How many of these charges are linked to a sales invoice", "title": "Invoiced Count", "type": "integer"}, "charges": {"description": "The individual charges, ordered by charge date", "items": {"$ref": "#/components/schemas/TurbineProgressCharge"}, "title": "Charges", "type": "array"}}, "title": "TurbineProgressChargeGroup", "type": "object"}, "TurbinesProgress": {"additionalProperties": false, "description": "Turbine charge progress for a sales order, sourced from local DB.", "properties": {"assets": {"items": {"$ref": "#/components/schemas/TurbineProgressAsset"}, "title": "Assets", "type": "array"}, "total_count": {"description": "Number of turbines in planned scope", "title": "Total Count", "type": "integer"}, "charged_count": {"description": "Number of unique turbines with at least one charge", "title": "Charged Count", "type": "integer"}}, "required": ["total_count", "charged_count"], "title": "TurbinesProgress", "type": "object"}, "NSSubsidiaryListItem": {"description": "NetSuite Subsidiary.", "properties": {"id": {"description": "NetSuite ID", "title": "Id", "type": "integer"}, "name": {"description": "Name", "title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "NSSubsidiaryListItem", "type": "object"}, "ServiceRateItem": {"additionalProperties": false, "description": "One service rate row per service for the OPS_HUB sidebar.\n\nA service can be priced by several CO lines (one per asset). Those lines are\ncollapsed into a single row: ``co_item_ids`` holds every contributing CO line\nand ``rate`` is only set when they all agree on one price \u2014 otherwise it is\n``None`` and the real rate is picked per asset in the charge-creation modal.", "properties": {"service_id": {"title": "Service Id", "type": "integer"}, "service_code": {"title": "Service Code", "type": "string"}, "service_name": {"title": "Service Name", "type": "string"}, "service_netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite item id of the service \u2014 lets the frontend address the NS line item when it falls back to the legacy charge flow for services without scope items (EXTRA, MOB, ACC, ...)", "title": "Service Netsuite Id"}, "rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Unit rate when every CO line for this service shares one price; None when they differ \u2014 the rate then comes from the asset's own CO line, chosen in the charge-creation modal", "title": "Rate"}, "has_scope_items": {"default": false, "title": "Has Scope Items", "type": "boolean"}, "has_linked_scope_items": {"default": false, "title": "Has Linked Scope Items", "type": "boolean"}, "co_item_ids": {"description": "Every CO line item ID priced under this service \u2014 the modal resolves assets across all of them", "items": {"type": "integer"}, "title": "Co Item Ids", "type": "array"}}, "required": ["service_id", "service_code", "service_name", "co_item_ids"], "title": "ServiceRateItem", "type": "object"}, "ChargeCreationContext": {"additionalProperties": false, "description": "All data needed to open the charge creation modal \u2014 100% local DB.", "properties": {"services": {"items": {"$ref": "#/components/schemas/ChargeCreationService"}, "title": "Services", "type": "array"}, "project_robot_sets": {"description": "All robot sets that worked on any SOL in this project", "items": {"$ref": "#/components/schemas/ChargeCreationRobotSet"}, "title": "Project Robot Sets", "type": "array"}}, "title": "ChargeCreationContext", "type": "object"}, "ChargeCreationRobotSet": {"additionalProperties": false, "description": "Robot set with id and name.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "ChargeCreationRobotSet", "type": "object"}, "ChargeCreationScopeItem": {"additionalProperties": false, "description": "Scope item for charge creation.\n\ndispatch_sol_ids contains all SOL IDs that the created charge will cover.\nFor a blade-level scope item this is a single ID. For a WTG whose CO line is\nWTG-scoped but scope items are individual blades, all blade SOL IDs are grouped\nhere and one charge is created covering all of them.", "properties": {"scope_item_id": {"title": "Scope Item Id", "type": "integer"}, "dispatch_sol_ids": {"items": {"type": "integer"}, "title": "Dispatch Sol Ids", "type": "array"}, "asset_identity": {"description": "e.g. 'WTG 1_06_S' (grouped blades) or 'WTG 1_06_S - Blade - A'", "title": "Asset Identity", "type": "string"}, "field_completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Date the SOL reached FIELD_COMPLETED status", "title": "Field Completed Date"}, "robot_sets": {"items": {"$ref": "#/components/schemas/ChargeCreationRobotSet"}, "title": "Robot Sets", "type": "array"}}, "required": ["scope_item_id", "dispatch_sol_ids", "asset_identity"], "title": "ChargeCreationScopeItem", "type": "object"}, "ChargeCreationService": {"additionalProperties": false, "description": "Service with its scope items for charge creation.", "properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}, "rate": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Rate"}, "co_item_id": {"description": "CO line item ID \u2014 used to identify the NS SO line for price sync", "title": "Co Item Id", "type": "integer"}, "scope_items": {"items": {"$ref": "#/components/schemas/ChargeCreationScopeItem"}, "title": "Scope Items", "type": "array"}}, "required": ["id", "code", "name", "co_item_id"], "title": "ChargeCreationService", "type": "object"}, "ScopeChargePOST": {"additionalProperties": false, "description": "Request body for creating a charge from a scope item (OPS_HUB flow).", "properties": {"scope_item_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Scope Item Id"}, "dispatch_sol_ids": {"description": "All dispatch SOL IDs this charge covers (0 when none available, 1 for blade, N for WTG with blade scope items)", "items": {"type": "integer"}, "title": "Dispatch Sol Ids", "type": "array"}, "service_id": {"title": "Service Id", "type": "integer"}, "co_item_id": {"title": "Co Item Id", "type": "integer"}, "robot_set_id": {"title": "Robot Set Id", "type": "integer"}, "charge_date": {"format": "date", "title": "Charge Date", "type": "string"}, "quantity": {"title": "Quantity", "type": "number"}, "status": {"allOf": [{"$ref": "#/components/schemas/ChargeStatusName"}], "default": "DRAFT"}}, "required": ["service_id", "co_item_id", "robot_set_id", "charge_date", "quantity"], "title": "ScopeChargePOST", "type": "object"}, "CommercialOfferListQuery": {"additionalProperties": false, "description": "Query parameters for commercial offer list endpoint.", "properties": {"page": {"default": 1, "minimum": 1, "title": "Page", "type": "integer"}, "page_size": {"default": 50, "maximum": 200, "minimum": 1, "title": "Page Size", "type": "integer"}, "include_approved": {"default": false, "title": "Include Approved", "type": "boolean"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Required Approver Role"}, "ordering": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "-id", "title": "Ordering"}}, "title": "CommercialOfferListQuery", "type": "object"}, "CommercialOfferRow": {"additionalProperties": false, "description": "Commercial offer summary row for table responses.", "properties": {"id": {"title": "Id", "type": "integer"}, "project_id": {"format": "uuid", "title": "Project Id", "type": "string"}, "updated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Updated At"}, "version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Version"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Currency"}, "final_sum": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Final Sum"}, "discount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Discount"}, "status": {"title": "Status", "type": "string"}, "creator_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Creator Email"}, "reviewer_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reviewer Email"}, "sales_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sales Comment"}, "required_approver_role": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Required Approver Role"}, "project_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Project Code"}, "company_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Company Name"}}, "required": ["id", "project_id", "updated_at", "version", "currency", "final_sum", "discount", "status"], "title": "CommercialOfferRow", "type": "object"}, "CommercialOfferBulkApproveResponse": {"additionalProperties": false, "description": "Response describing which offers were approved or skipped.", "properties": {"approved": {"items": {"type": "integer"}, "title": "Approved", "type": "array"}, "skipped": {"items": {"type": "integer"}, "title": "Skipped", "type": "array"}}, "required": ["approved", "skipped"], "title": "CommercialOfferBulkApproveResponse", "type": "object"}, "CommercialOfferApproveRequest": {"additionalProperties": false, "description": "Request payload for bulk commercial offer approval.", "properties": {"ids": {"items": {"type": "integer"}, "title": "Ids", "type": "array"}}, "required": ["ids"], "title": "CommercialOfferApproveRequest", "type": "object"}, "AccountingOverviewQuery": {"additionalProperties": false, "description": "Query parameters for accounting overview endpoint.", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by project code (partial matching)", "title": "Search"}, "clients": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client names (comma-separated)", "title": "Clients"}, "pm": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project managers (comma-separated)", "title": "Pm"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by countries (comma-separated)", "title": "Country"}, "project_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by core project status (comma-separated)", "title": "Project Status"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billable service code (comma-separated)", "title": "Service Code"}, "service_unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service unit type (comma-separated)", "title": "Service Unit Type"}, "robot_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robot set (comma-separated)", "title": "Robot Set"}, "total_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue (in project currency)", "title": "Total Revenue Min"}, "total_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue (in project currency)", "title": "Total Revenue Max"}, "total_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in EUR", "title": "Total Revenue Eur Min"}, "total_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in EUR", "title": "Total Revenue Eur Max"}, "total_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in USD", "title": "Total Revenue Usd Min"}, "total_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in USD", "title": "Total Revenue Usd Max"}, "total_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in AUD", "title": "Total Revenue Aud Min"}, "total_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in AUD", "title": "Total Revenue Aud Max"}, "added_to_invoice_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Min"}, "added_to_invoice_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Max"}, "added_to_invoice_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Min"}, "added_to_invoice_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Max"}, "added_to_invoice_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Min"}, "added_to_invoice_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Max"}, "added_to_invoice_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Min"}, "added_to_invoice_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Max"}, "actual_planned_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Min"}, "actual_planned_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Max"}, "actual_planned_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Min"}, "actual_planned_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Max"}, "actual_planned_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Min"}, "actual_planned_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Max"}, "actual_planned_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Min"}, "actual_planned_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Max"}, "total_quantity_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum total quantity", "title": "Total Quantity Min"}, "total_quantity_max": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum total quantity", "title": "Total Quantity Max"}, "actual_planned_quantity_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned quantity", "title": "Actual Planned Quantity Min"}, "actual_planned_quantity_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned quantity", "title": "Actual Planned Quantity Max"}, "fixed_planned_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Min"}, "fixed_planned_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Max"}, "fixed_planned_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Min"}, "fixed_planned_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Max"}, "fixed_planned_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Min"}, "fixed_planned_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Max"}, "fixed_planned_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Min"}, "fixed_planned_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Max"}, "invoiced_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue (in project currency)", "title": "Invoiced Revenue Min"}, "invoiced_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue (in project currency)", "title": "Invoiced Revenue Max"}, "invoiced_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Min"}, "invoiced_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Max"}, "invoiced_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in USD", "title": "Invoiced Revenue Usd Min"}, "invoiced_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in USD", "title": "Invoiced Revenue Usd Max"}, "invoiced_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Min"}, "invoiced_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Max"}, "draft_charges_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges (in project currency)", "title": "Draft Charges Min"}, "draft_charges_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges (in project currency)", "title": "Draft Charges Max"}, "draft_charges_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in EUR", "title": "Draft Charges Eur Min"}, "draft_charges_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in EUR", "title": "Draft Charges Eur Max"}, "draft_charges_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in USD", "title": "Draft Charges Usd Min"}, "draft_charges_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in USD", "title": "Draft Charges Usd Max"}, "draft_charges_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in AUD", "title": "Draft Charges Aud Min"}, "draft_charges_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in AUD", "title": "Draft Charges Aud Max"}, "approved_charges_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges (in project currency)", "title": "Approved Charges Min"}, "approved_charges_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges (in project currency)", "title": "Approved Charges Max"}, "approved_charges_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in EUR", "title": "Approved Charges Eur Min"}, "approved_charges_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in EUR", "title": "Approved Charges Eur Max"}, "approved_charges_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in USD", "title": "Approved Charges Usd Min"}, "approved_charges_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in USD", "title": "Approved Charges Usd Max"}, "approved_charges_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in AUD", "title": "Approved Charges Aud Min"}, "approved_charges_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in AUD", "title": "Approved Charges Aud Max"}, "require_po_charges_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges (in project currency)", "title": "Require Po Charges Min"}, "require_po_charges_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges (in project currency)", "title": "Require Po Charges Max"}, "require_po_charges_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in EUR", "title": "Require Po Charges Eur Min"}, "require_po_charges_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in EUR", "title": "Require Po Charges Eur Max"}, "require_po_charges_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in USD", "title": "Require Po Charges Usd Min"}, "require_po_charges_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in USD", "title": "Require Po Charges Usd Max"}, "require_po_charges_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in AUD", "title": "Require Po Charges Aud Min"}, "require_po_charges_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in AUD", "title": "Require Po Charges Aud Max"}, "closure_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date start", "title": "Closure Start Date"}, "closure_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date end", "title": "Closure End Date"}, "has_unresolved_comments": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by projects with unresolved comments", "title": "Has Unresolved Comments"}, "page": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1, "description": "Page number for pagination", "title": "Page"}, "page_size": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": 1000, "description": "Number of items per page", "title": "Page Size"}, "sort_by": {"anyOf": [{"$ref": "#/components/schemas/AccountingOverviewSortBy"}, {"type": "null"}], "description": "Field to sort by"}, "sort_order": {"anyOf": [{"enum": ["asc", "desc"], "type": "string"}, {"type": "null"}], "default": "asc", "description": "Sort order (asc or desc)", "title": "Sort Order"}}, "title": "AccountingOverviewQuery", "type": "object"}, "AccountingOverviewSortBy": {"description": "Sortable fields for accounting overview.", "enum": ["code", "robot_set_name", "client", "country", "total_quantity", "total_revenue", "total_revenue_eur", "total_revenue_usd", "total_revenue_aud", "added_to_invoice_revenue", "added_to_invoice_revenue_eur", "added_to_invoice_revenue_usd", "added_to_invoice_revenue_aud", "invoiced_revenue", "invoiced_revenue_eur", "invoiced_revenue_usd", "invoiced_revenue_aud", "draft_charges", "draft_charges_eur", "draft_charges_usd", "draft_charges_aud", "approved_charges", "approved_charges_eur", "approved_charges_usd", "approved_charges_aud", "require_po_charges", "require_po_charges_eur", "require_po_charges_usd", "require_po_charges_aud", "currency", "actual_planned_quantity", "actual_planned_revenue", "actual_planned_revenue_eur", "actual_planned_revenue_usd", "actual_planned_revenue_aud", "fixed_planned_revenue", "fixed_planned_revenue_eur", "fixed_planned_revenue_usd", "fixed_planned_revenue_aud", "project_status", "service_codes", "service_unit_types", "closure_date"], "title": "AccountingOverviewSortBy", "type": "string"}, "ProjectRevenue": {"additionalProperties": false, "description": "Schema for project revenue.", "properties": {"id": {"description": "UUID of the project", "format": "uuid", "title": "Id", "type": "string"}, "code": {"description": "Code of the project", "title": "Code", "type": "string"}, "robot_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name of robot set", "title": "Robot Set Name"}, "client": {"anyOf": [{"$ref": "#/components/schemas/Client"}, {"type": "null"}], "description": "Client of the project"}, "country": {"anyOf": [{"$ref": "#/components/schemas/Country"}, {"type": "null"}], "description": "Country of the project"}, "total_quantity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Total quantity of unique assets charged", "title": "Total Quantity"}, "blade_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Count of unique blades (turbine components) charged", "title": "Blade Count"}, "wtg_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Count of unique WTGs (turbines) charged via WTG-level scope items", "title": "Wtg Count"}, "total_revenue": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in project's currency", "title": "Total Revenue"}, "total_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in EUR", "title": "Total Revenue Eur"}, "total_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in USD", "title": "Total Revenue Usd"}, "total_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in AUD", "title": "Total Revenue Aud"}, "added_to_invoice_revenue": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total added to invoice revenue in project's currency", "title": "Added To Invoice Revenue"}, "added_to_invoice_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur"}, "added_to_invoice_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd"}, "added_to_invoice_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud"}, "invoiced_revenue": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges where invoice_sent_status is Final (project currency)", "title": "Invoiced Revenue"}, "invoiced_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges where invoice_sent_status is Final (EUR)", "title": "Invoiced Revenue Eur"}, "invoiced_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges where invoice_sent_status is Final (USD)", "title": "Invoiced Revenue Usd"}, "invoiced_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges where invoice_sent_status is Final (AUD)", "title": "Invoiced Revenue Aud"}, "draft_charges": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in DRAFT status (project currency)", "title": "Draft Charges"}, "draft_charges_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in DRAFT status (EUR)", "title": "Draft Charges Eur"}, "draft_charges_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in DRAFT status (USD)", "title": "Draft Charges Usd"}, "draft_charges_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in DRAFT status (AUD)", "title": "Draft Charges Aud"}, "approved_charges": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in APPROVED status (project currency)", "title": "Approved Charges"}, "approved_charges_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in APPROVED status (EUR)", "title": "Approved Charges Eur"}, "approved_charges_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in APPROVED status (USD)", "title": "Approved Charges Usd"}, "approved_charges_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in APPROVED status (AUD)", "title": "Approved Charges Aud"}, "require_po_charges": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in REQUIRE_PO status (project currency)", "title": "Require Po Charges"}, "require_po_charges_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in REQUIRE_PO status (EUR)", "title": "Require Po Charges Eur"}, "require_po_charges_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in REQUIRE_PO status (USD)", "title": "Require Po Charges Usd"}, "require_po_charges_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Sum of charges in REQUIRE_PO status (AUD)", "title": "Require Po Charges Aud"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency name", "title": "Currency"}, "actual_planned_quantity": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned quantity", "title": "Actual Planned Quantity"}, "actual_planned_revenue": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue", "title": "Actual Planned Revenue"}, "actual_planned_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue in EUR", "title": "Actual Planned Revenue Eur"}, "actual_planned_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue in USD", "title": "Actual Planned Revenue Usd"}, "actual_planned_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue in AUD", "title": "Actual Planned Revenue Aud"}, "fixed_planned_revenue": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue (based on month start dates)", "title": "Fixed Planned Revenue"}, "fixed_planned_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur"}, "fixed_planned_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd"}, "fixed_planned_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud"}, "project_managers": {"default": [], "description": "Project manager from core.Project (at most one)", "items": {"type": "string"}, "title": "Project Managers", "type": "array"}, "project_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Core project status code, canonicalized (e.g. EXECUTION)", "title": "Project Status"}, "service_codes": {"default": [], "description": "Billable service codes charged on this project/robot-set", "items": {"type": "string"}, "title": "Service Codes", "type": "array"}, "service_unit_types": {"default": [], "description": "Component types the charged services are performed on (WTG when untied)", "items": {"type": "string"}, "title": "Service Unit Types", "type": "array"}, "closure_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "When the project most recently entered 'Closure'", "title": "Closure Date"}, "has_unresolved_comments": {"default": false, "description": "Project has unresolved comments in date range", "title": "Has Unresolved Comments", "type": "boolean"}, "project_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Truncated project description from project overview info", "title": "Project Description"}, "project_overview_link": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Link to project overview page", "title": "Project Overview Link"}}, "required": ["id", "code"], "title": "ProjectRevenue", "type": "object"}, "AccountingOverviewSummaryQuery": {"additionalProperties": false, "description": "Query parameters for accounting overview summary endpoint (without pagination).", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by project code (partial matching)", "title": "Search"}, "clients": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by client names (comma-separated)", "title": "Clients"}, "pm": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by project managers (comma-separated)", "title": "Pm"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by countries (comma-separated)", "title": "Country"}, "project_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by core project status (comma-separated)", "title": "Project Status"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billable service code (comma-separated)", "title": "Service Code"}, "service_unit_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service unit type (comma-separated)", "title": "Service Unit Type"}, "robot_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robot set (comma-separated)", "title": "Robot Set"}, "total_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue (in project currency)", "title": "Total Revenue Min"}, "total_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue (in project currency)", "title": "Total Revenue Max"}, "total_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in EUR", "title": "Total Revenue Eur Min"}, "total_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in EUR", "title": "Total Revenue Eur Max"}, "total_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in USD", "title": "Total Revenue Usd Min"}, "total_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in USD", "title": "Total Revenue Usd Max"}, "total_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum total revenue in AUD", "title": "Total Revenue Aud Min"}, "total_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum total revenue in AUD", "title": "Total Revenue Aud Max"}, "added_to_invoice_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Min"}, "added_to_invoice_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue (in project currency)", "title": "Added To Invoice Revenue Max"}, "added_to_invoice_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Min"}, "added_to_invoice_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur Max"}, "added_to_invoice_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Min"}, "added_to_invoice_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd Max"}, "added_to_invoice_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Min"}, "added_to_invoice_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud Max"}, "actual_planned_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Min"}, "actual_planned_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue (in project currency)", "title": "Actual Planned Revenue Max"}, "actual_planned_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Min"}, "actual_planned_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in EUR", "title": "Actual Planned Revenue Eur Max"}, "actual_planned_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Min"}, "actual_planned_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in USD", "title": "Actual Planned Revenue Usd Max"}, "actual_planned_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Min"}, "actual_planned_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned revenue in AUD", "title": "Actual Planned Revenue Aud Max"}, "total_quantity_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum total quantity", "title": "Total Quantity Min"}, "total_quantity_max": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum total quantity", "title": "Total Quantity Max"}, "actual_planned_quantity_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned quantity", "title": "Actual Planned Quantity Min"}, "actual_planned_quantity_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned quantity", "title": "Actual Planned Quantity Max"}, "fixed_planned_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Min"}, "fixed_planned_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue (in project currency)", "title": "Fixed Planned Revenue Max"}, "fixed_planned_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Min"}, "fixed_planned_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur Max"}, "fixed_planned_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Min"}, "fixed_planned_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd Max"}, "fixed_planned_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Min"}, "fixed_planned_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud Max"}, "invoiced_revenue_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue (in project currency)", "title": "Invoiced Revenue Min"}, "invoiced_revenue_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue (in project currency)", "title": "Invoiced Revenue Max"}, "invoiced_revenue_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Min"}, "invoiced_revenue_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in EUR", "title": "Invoiced Revenue Eur Max"}, "invoiced_revenue_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in USD", "title": "Invoiced Revenue Usd Min"}, "invoiced_revenue_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in USD", "title": "Invoiced Revenue Usd Max"}, "invoiced_revenue_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Min"}, "invoiced_revenue_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum invoiced revenue in AUD", "title": "Invoiced Revenue Aud Max"}, "draft_charges_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges (in project currency)", "title": "Draft Charges Min"}, "draft_charges_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges (in project currency)", "title": "Draft Charges Max"}, "draft_charges_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in EUR", "title": "Draft Charges Eur Min"}, "draft_charges_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in EUR", "title": "Draft Charges Eur Max"}, "draft_charges_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in USD", "title": "Draft Charges Usd Min"}, "draft_charges_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in USD", "title": "Draft Charges Usd Max"}, "draft_charges_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum draft charges in AUD", "title": "Draft Charges Aud Min"}, "draft_charges_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum draft charges in AUD", "title": "Draft Charges Aud Max"}, "approved_charges_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges (in project currency)", "title": "Approved Charges Min"}, "approved_charges_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges (in project currency)", "title": "Approved Charges Max"}, "approved_charges_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in EUR", "title": "Approved Charges Eur Min"}, "approved_charges_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in EUR", "title": "Approved Charges Eur Max"}, "approved_charges_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in USD", "title": "Approved Charges Usd Min"}, "approved_charges_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in USD", "title": "Approved Charges Usd Max"}, "approved_charges_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum approved charges in AUD", "title": "Approved Charges Aud Min"}, "approved_charges_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum approved charges in AUD", "title": "Approved Charges Aud Max"}, "require_po_charges_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges (in project currency)", "title": "Require Po Charges Min"}, "require_po_charges_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges (in project currency)", "title": "Require Po Charges Max"}, "require_po_charges_eur_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in EUR", "title": "Require Po Charges Eur Min"}, "require_po_charges_eur_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in EUR", "title": "Require Po Charges Eur Max"}, "require_po_charges_usd_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in USD", "title": "Require Po Charges Usd Min"}, "require_po_charges_usd_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in USD", "title": "Require Po Charges Usd Max"}, "require_po_charges_aud_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum require-PO charges in AUD", "title": "Require Po Charges Aud Min"}, "require_po_charges_aud_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum require-PO charges in AUD", "title": "Require Po Charges Aud Max"}, "closure_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date start", "title": "Closure Start Date"}, "closure_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by project closure date end", "title": "Closure End Date"}, "has_unresolved_comments": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by projects with unresolved comments", "title": "Has Unresolved Comments"}}, "title": "AccountingOverviewSummaryQuery", "type": "object"}, "AccountingOverviewSummary": {"additionalProperties": false, "description": "Summary schema for accounting overview aggregated data.", "properties": {"client_count": {"description": "Total amount of unique clients", "title": "Client Count", "type": "integer"}, "project_count": {"description": "Total amount of projects", "title": "Project Count", "type": "integer"}, "total_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in EUR", "title": "Total Revenue Eur"}, "total_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in USD", "title": "Total Revenue Usd"}, "total_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Total revenue in AUD", "title": "Total Revenue Aud"}, "added_to_invoice_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Added to invoice revenue in EUR", "title": "Added To Invoice Revenue Eur"}, "added_to_invoice_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Added to invoice revenue in USD", "title": "Added To Invoice Revenue Usd"}, "added_to_invoice_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Added to invoice revenue in AUD", "title": "Added To Invoice Revenue Aud"}, "invoiced_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Invoiced revenue in EUR (invoice_sent_status=Final)", "title": "Invoiced Revenue Eur"}, "invoiced_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Invoiced revenue in USD (invoice_sent_status=Final)", "title": "Invoiced Revenue Usd"}, "invoiced_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Invoiced revenue in AUD (invoice_sent_status=Final)", "title": "Invoiced Revenue Aud"}, "draft_charges_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Draft charges in EUR", "title": "Draft Charges Eur"}, "draft_charges_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Draft charges in USD", "title": "Draft Charges Usd"}, "draft_charges_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Draft charges in AUD", "title": "Draft Charges Aud"}, "approved_charges_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approved charges in EUR", "title": "Approved Charges Eur"}, "approved_charges_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approved charges in USD", "title": "Approved Charges Usd"}, "approved_charges_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approved charges in AUD", "title": "Approved Charges Aud"}, "require_po_charges_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Require-PO charges in EUR", "title": "Require Po Charges Eur"}, "require_po_charges_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Require-PO charges in USD", "title": "Require Po Charges Usd"}, "require_po_charges_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Require-PO charges in AUD", "title": "Require Po Charges Aud"}, "actual_planned_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue in EUR", "title": "Actual Planned Revenue Eur"}, "actual_planned_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue in USD", "title": "Actual Planned Revenue Usd"}, "actual_planned_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Actual planned revenue in AUD", "title": "Actual Planned Revenue Aud"}, "fixed_planned_revenue_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue in EUR", "title": "Fixed Planned Revenue Eur"}, "fixed_planned_revenue_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue in USD", "title": "Fixed Planned Revenue Usd"}, "fixed_planned_revenue_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Fixed planned revenue in AUD", "title": "Fixed Planned Revenue Aud"}}, "required": ["client_count", "project_count"], "title": "AccountingOverviewSummary", "type": "object"}, "AccountingOverviewFiltersQuery": {"additionalProperties": false, "description": "Query parameters for accounting overview filters endpoint (date filters only).", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Start date for filtering charges", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "End date for filtering charges", "title": "End Date"}}, "title": "AccountingOverviewFiltersQuery", "type": "object"}, "AccountingOverviewFilters": {"additionalProperties": false, "description": "Filters schema for accounting overview unique values.", "properties": {"clients": {"description": "All client names found in accounting overview dataset", "items": {"type": "string"}, "title": "Clients", "type": "array"}, "pm": {"description": "All project managers found in projects", "items": {"type": "string"}, "title": "Pm", "type": "array"}, "regions": {"description": "All regions (continents) from projects", "items": {"type": "string"}, "title": "Regions", "type": "array"}, "countries": {"description": "All countries used in projects", "items": {"type": "string"}, "title": "Countries", "type": "array"}, "project_status": {"description": "All core project statuses found in projects", "items": {"type": "string"}, "title": "Project Status", "type": "array"}, "service_code": {"description": "All billable service codes found in charges", "items": {"type": "string"}, "title": "Service Code", "type": "array"}, "service_unit_type": {"description": "All service unit types found in charges", "items": {"type": "string"}, "title": "Service Unit Type", "type": "array"}, "robot_set": {"description": "All robot sets found in projects", "items": {"type": "string"}, "title": "Robot Set", "type": "array"}}, "required": ["clients", "pm", "regions", "countries", "project_status", "service_code", "service_unit_type", "robot_set"], "title": "AccountingOverviewFilters", "type": "object"}, "MissingChargesTrackerQuery": {"additionalProperties": false, "description": "Query parameters for missing charges tracker endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search term for project code or set name", "title": "Search"}, "reason_filter": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by reason type: 'charge-entry', 'sales-order-missing', or None for all.", "title": "Reason Filter"}, "project_codes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project codes to filter by", "title": "Project Codes"}, "set_names": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of set names to filter by", "title": "Set Names"}, "project_managers": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project manager names to filter by", "title": "Project Managers"}, "delay_days_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum delay days filter", "title": "Delay Days Min"}, "delay_days_max": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum delay days filter", "title": "Delay Days Max"}, "date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates from this date (inclusive)", "title": "Date From"}, "date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates to this date (inclusive)", "title": "Date To"}, "sort_field": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Field to sort by: projectCode, setName, delayDays, workDate, suggestedAmount, reasons, comment", "title": "Sort Field"}, "sort_order": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort order: 'ascend' or 'descend'", "title": "Sort Order"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "EUR", "description": "Display currency for approximate amounts: EUR, USD, or AUD", "title": "Currency"}, "exclude_sundays": {"default": false, "description": "If True, exclude Sunday records from results.", "title": "Exclude Sundays", "type": "boolean"}, "hide_with_comments": {"default": false, "description": "If True, exclude records that have a comment.", "title": "Hide With Comments", "type": "boolean"}, "page": {"default": 1, "description": "Page number", "minimum": 1, "title": "Page", "type": "integer"}, "page_size": {"default": 10, "description": "Items per page", "maximum": 1000, "minimum": 1, "title": "Page Size", "type": "integer"}, "use_cache": {"default": true, "description": "If True, read from cache. If False, fetch live data.", "title": "Use Cache", "type": "boolean"}}, "title": "MissingChargesTrackerQuery", "type": "object"}, "MissingChargesAffectedProject": {"additionalProperties": false, "description": "Project impacted by missing charges.", "properties": {"project_code": {"description": "Project code", "title": "Project Code", "type": "string"}, "project_id": {"description": "Project UUID", "title": "Project Id", "type": "string"}}, "required": ["project_code", "project_id"], "title": "MissingChargesAffectedProject", "type": "object"}, "MissingChargesTrackerResponse": {"additionalProperties": false, "description": "Response for missing charges tracker endpoint.", "properties": {"total_missing_records": {"description": "Total number of robot sets with missing data", "title": "Total Missing Records", "type": "integer"}, "projects_affected": {"description": "Number of unique projects affected", "title": "Projects Affected", "type": "integer"}, "critical_count": {"description": "Number of records with 3+ days delay", "title": "Critical Count", "type": "integer"}, "total_suggested_amount": {"default": 0.0, "description": "Sum of suggested amounts across all missing records in project currency", "title": "Total Suggested Amount", "type": "number"}, "total_suggested_amount_eur": {"default": 0.0, "description": "Sum of suggested amounts converted to EUR", "title": "Total Suggested Amount Eur", "type": "number"}, "total_suggested_amount_usd": {"default": 0.0, "description": "Sum of suggested amounts converted to USD", "title": "Total Suggested Amount Usd", "type": "number"}, "total_suggested_amount_aud": {"default": 0.0, "description": "Sum of suggested amounts converted to AUD", "title": "Total Suggested Amount Aud", "type": "number"}, "daily_reports_missing": {"description": "Legacy metric, kept for compatibility (always 0)", "title": "Daily Reports Missing", "type": "integer"}, "available_project_codes": {"description": "List of available project codes after filters", "items": {"type": "string"}, "title": "Available Project Codes", "type": "array"}, "available_set_names": {"description": "List of available set names after filters", "items": {"type": "string"}, "title": "Available Set Names", "type": "array"}, "available_project_managers": {"description": "List of available project managers for filtering", "items": {"type": "string"}, "title": "Available Project Managers", "type": "array"}, "affected_projects": {"description": "List of affected projects after filters", "items": {"$ref": "#/components/schemas/MissingChargesAffectedProject"}, "title": "Affected Projects", "type": "array"}, "available_reasons": {"description": "List of all available reason badges for filtering", "items": {"$ref": "#/components/schemas/MissingDataReasonBadge"}, "title": "Available Reasons", "type": "array"}, "items": {"description": "List of robot sets with missing data", "items": {"$ref": "#/components/schemas/RobotSetMissingData"}, "title": "Items", "type": "array"}, "last_synced_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Timestamp of last cache sync (None if using live data)", "title": "Last Synced At"}, "platform_projects_not_found": {"description": "Project codes not found in Platform API", "items": {"type": "string"}, "title": "Platform Projects Not Found", "type": "array"}, "projects_mapped": {"default": 0, "description": "Projects mapped to internal IDs", "title": "Projects Mapped", "type": "integer"}, "projects_total": {"default": 0, "description": "Total projects observed in the data set", "title": "Projects Total", "type": "integer"}, "workload_fetch_failed_count": {"default": 0, "description": "Number of projects where workload fetch failed", "title": "Workload Fetch Failed Count", "type": "integer"}, "workload_auth_missing": {"default": false, "description": "True if workload fetch skipped due to missing auth", "title": "Workload Auth Missing", "type": "boolean"}, "projects_missing_in_db": {"description": "Project codes missing in internal Projects table", "items": {"type": "string"}, "title": "Projects Missing In Db", "type": "array"}, "planned_projects_discovered": {"default": 0, "description": "Number of project codes discovered from planned resource sets", "title": "Planned Projects Discovered", "type": "integer"}, "planned_only_projects": {"default": 0, "description": "Projects found via planned resource sets but not in NetSuite charges", "title": "Planned Only Projects", "type": "integer"}}, "required": ["total_missing_records", "projects_affected", "critical_count", "daily_reports_missing", "available_project_codes", "available_set_names", "affected_projects", "available_reasons", "items"], "title": "MissingChargesTrackerResponse", "type": "object"}, "MissingDataReasonBadge": {"additionalProperties": false, "description": "Badge showing reason for missing data.", "properties": {"type": {"description": "Reason type: 'charge-entry' or 'sales-order-missing'", "title": "Type", "type": "string"}, "label": {"description": "Display text for the reason badge", "title": "Label", "type": "string"}}, "required": ["type", "label"], "title": "MissingDataReasonBadge", "type": "object"}, "RobotSetMissingData": {"additionalProperties": false, "description": "Missing data tracking for a robot set.", "properties": {"project_code": {"description": "Project code", "title": "Project Code", "type": "string"}, "project_id": {"description": "Project UUID", "title": "Project Id", "type": "string"}, "set_name": {"description": "Robot set name", "title": "Set Name", "type": "string"}, "set_id": {"description": "core.RobotSet id", "title": "Set Id", "type": "integer"}, "work_date": {"description": "Date of the work being tracked", "format": "date", "title": "Work Date", "type": "string"}, "delay_days": {"description": "Days since last work performed", "title": "Delay Days", "type": "integer"}, "last_charge_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Most recent date with charge entry", "title": "Last Charge Date"}, "reasons": {"description": "List of reasons for missing data", "items": {"$ref": "#/components/schemas/MissingDataReasonBadge"}, "title": "Reasons", "type": "array"}, "project_managers": {"default": [], "description": "List of project managers for this project (from core.Project)", "items": {"type": "string"}, "title": "Project Managers", "type": "array"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comment from accounting notes", "title": "Comment"}, "expected_charges": {"default": [], "description": "List of expected charge types based on set status and CO line items", "items": {"type": "string"}, "title": "Expected Charges", "type": "array"}, "suggested_amount": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approximate revenue from suggested charges", "title": "Suggested Amount"}, "suggested_amount_eur": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approximate revenue converted to EUR", "title": "Suggested Amount Eur"}, "suggested_amount_usd": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approximate revenue converted to USD", "title": "Suggested Amount Usd"}, "suggested_amount_aud": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Approximate revenue converted to AUD", "title": "Suggested Amount Aud"}}, "required": ["project_code", "project_id", "set_name", "set_id", "work_date", "delay_days", "reasons"], "title": "RobotSetMissingData", "type": "object"}, "MissingChargesSyncResponse": {"additionalProperties": false, "description": "Response for missing charges sync endpoint.", "properties": {"total_records": {"description": "Total records synced", "title": "Total Records", "type": "integer"}, "deleted": {"description": "Records deleted from cache", "title": "Deleted", "type": "integer"}, "created": {"description": "Records created in cache", "title": "Created", "type": "integer"}, "duration_seconds": {"description": "Sync duration in seconds", "title": "Duration Seconds", "type": "number"}, "synced_at": {"description": "Sync timestamp (ISO format)", "title": "Synced At", "type": "string"}}, "required": ["total_records", "deleted", "created", "duration_seconds", "synced_at"], "title": "MissingChargesSyncResponse", "type": "object"}, "MissingChargesCacheStatus": {"additionalProperties": false, "description": "Response for cache status endpoint.", "properties": {"cached_records": {"description": "Number of cached records", "title": "Cached Records", "type": "integer"}, "last_synced_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Last sync timestamp (ISO format)", "title": "Last Synced At"}, "is_empty": {"description": "True if cache is empty", "title": "Is Empty", "type": "boolean"}}, "required": ["cached_records", "is_empty"], "title": "MissingChargesCacheStatus", "type": "object"}, "ChargeBulkReviewResponse": {"additionalProperties": false, "description": "Response for bulk PM/customer review-status transitions.", "properties": {"updated_ids": {"description": "IDs of charges that were transitioned", "items": {"type": "integer"}, "title": "Updated Ids", "type": "array"}}, "required": ["updated_ids"], "title": "ChargeBulkReviewResponse", "type": "object"}, "ChargeBulkReview": {"additionalProperties": false, "description": "Input for bulk PM/customer review-status transitions.\n\nExactly one of `ids` or `email_send_log_id` must be set. `ids` names the\ncharges directly; `email_send_log_id` resolves to every charge linked to\nthat sent email (`EmailSendLogCharge`).", "properties": {"ids": {"anyOf": [{"items": {"type": "integer"}, "minItems": 1, "type": "array"}, {"type": "null"}], "description": "List of charge IDs to transition", "title": "Ids"}, "email_send_log_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Transition every charge linked to this sent email", "title": "Email Send Log Id"}}, "title": "ChargeBulkReview", "type": "object"}, "NetSuiteLocalSyncResponse": {"additionalProperties": false, "description": "Response schema for the NetSuite local DB sync operation.", "properties": {"projects_synced": {"description": "Number of projects synced", "title": "Projects Synced", "type": "integer"}, "sales_orders_upserted": {"description": "Sales orders upserted", "title": "Sales Orders Upserted", "type": "integer"}, "line_items_upserted": {"description": "Line items upserted", "title": "Line Items Upserted", "type": "integer"}, "charges_upserted": {"description": "Charges upserted", "title": "Charges Upserted", "type": "integer"}, "invoices_upserted": {"description": "Invoices upserted", "title": "Invoices Upserted", "type": "integer"}, "duration_seconds": {"description": "Sync duration in seconds", "title": "Duration Seconds", "type": "number"}, "errors": {"description": "Per-project error messages", "items": {"type": "string"}, "title": "Errors", "type": "array"}}, "required": ["projects_synced", "sales_orders_upserted", "line_items_upserted", "charges_upserted", "invoices_upserted", "duration_seconds", "errors"], "title": "NetSuiteLocalSyncResponse", "type": "object"}, "MissingChargesTrackerExportQuery": {"additionalProperties": false, "description": "Query parameters for missing charges tracker export endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search term for project code or set name", "title": "Search"}, "reason_filter": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by reason type: 'charge-entry', 'sales-order-missing', or None for all.", "title": "Reason Filter"}, "project_codes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project codes to filter by", "title": "Project Codes"}, "set_names": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of set names to filter by", "title": "Set Names"}, "project_managers": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated list of project manager names to filter by", "title": "Project Managers"}, "delay_days_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Minimum delay days filter", "title": "Delay Days Min"}, "delay_days_max": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Maximum delay days filter", "title": "Delay Days Max"}, "date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates from this date (inclusive)", "title": "Date From"}, "date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter work dates to this date (inclusive)", "title": "Date To"}, "sort_field": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Field to sort by: projectCode, setName, delayDays, workDate, suggestedAmount, reasons, comment", "title": "Sort Field"}, "sort_order": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort order: 'ascend' or 'descend'", "title": "Sort Order"}, "currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "EUR", "description": "Display currency for approximate amounts: EUR, USD, or AUD", "title": "Currency"}, "exclude_sundays": {"default": false, "description": "If True, exclude Sunday records from results.", "title": "Exclude Sundays", "type": "boolean"}, "hide_with_comments": {"default": false, "description": "If True, exclude records that have a comment.", "title": "Hide With Comments", "type": "boolean"}}, "title": "MissingChargesTrackerExportQuery", "type": "object"}, "NetSuiteDepartmentQueryParams": {"additionalProperties": false, "description": "Query parameters for the NetSuite departments endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by department name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by NetSuite department ID", "title": "Netsuite Id"}, "is_inactive": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by the NetSuite inactive flag; omit to get active and inactive departments", "title": "Is Inactive"}}, "title": "NetSuiteDepartmentQueryParams", "type": "object"}, "NetSuiteDepartmentResponse": {"additionalProperties": false, "description": "Schema for a NetSuiteDepartment response, the cost center mirror row.", "properties": {"id": {"description": "Operations Hub row ID", "title": "Id", "type": "integer"}, "netsuite_id": {"description": "NetSuite department ID, the key of the mirror", "title": "Netsuite Id", "type": "integer"}, "name": {"description": "Department name", "title": "Name", "type": "string"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Name prefixed with the parent department names", "title": "Full Name"}, "external_id": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NetSuite external id, the cost center code (e.g. FINA)", "title": "External Id"}, "division_netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID of the division custom segment value", "title": "Division Netsuite Id"}, "division_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Division name", "title": "Division Name"}, "parent_netsuite_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite ID of the parent department", "title": "Parent Netsuite Id"}, "is_inactive": {"description": "Department is inactive in NetSuite", "title": "Is Inactive", "type": "boolean"}, "subsidiary_netsuite_ids": {"description": "NetSuite IDs of the subsidiaries the department applies to", "items": {"type": "integer"}, "title": "Subsidiary Netsuite Ids", "type": "array"}, "last_modified_at": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Department last modified date in NetSuite", "title": "Last Modified At"}, "synced_at": {"description": "When the sync last wrote this row", "format": "date-time", "title": "Synced At", "type": "string"}}, "required": ["id", "netsuite_id", "name", "is_inactive", "synced_at"], "title": "NetSuiteDepartmentResponse", "type": "object"}, "SalesOrderQueryParams": {"additionalProperties": false, "description": "Query parameters for sales orders endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}}, "title": "SalesOrderQueryParams", "type": "object"}, "SalesOrderResponse": {"additionalProperties": false, "description": "Schema for SalesOrder response.", "properties": {"id": {"description": "Sales order ID", "title": "Id", "type": "integer"}, "netsuite_sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite sales order ID", "title": "Netsuite Sales Order Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order status", "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "OpsHub customer ID", "title": "Customer Id"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Customer name", "title": "Customer Name"}, "sales_order_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order date", "title": "Sales Order Date"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "updated_at"], "title": "SalesOrderResponse", "type": "object"}, "SalesOrderCreate": {"additionalProperties": false, "description": "Schema for creating a SalesOrder.", "properties": {"netsuite_sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite sales order ID", "title": "Netsuite Sales Order Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order status", "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "OpsHub customer ID", "title": "Customer Id"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "customer_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Customer name", "title": "Customer Name"}, "sales_order_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order date (YYYY-MM-DD)", "title": "Sales Order Date"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}}, "title": "SalesOrderCreate", "type": "object"}, "SalesOrderUpdate": {"additionalProperties": false, "description": "Schema for updating a SalesOrder.", "properties": {"netsuite_sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite sales order ID", "title": "Netsuite Sales Order Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order status", "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "OpsHub customer ID", "title": "Customer Id"}, "netsuite_customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite customer ID", "title": "Netsuite Customer Id"}, "sales_order_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sales order date (YYYY-MM-DD)", "title": "Sales Order Date"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}}, "title": "SalesOrderUpdate", "type": "object"}, "SalesOrderLineQueryParams": {"additionalProperties": false, "description": "Query parameters for sales order lines endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sales order ID", "title": "Sales Order Id"}}, "title": "SalesOrderLineQueryParams", "type": "object"}, "SalesOrderLineResponse": {"additionalProperties": false, "description": "Schema for SalesOrderLine response.", "properties": {"id": {"description": "Line ID", "title": "Id", "type": "integer"}, "sales_order_id": {"description": "Parent sales order ID", "title": "Sales Order Id", "type": "integer"}, "netsuite_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite line ID", "title": "Netsuite Line Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code", "title": "Service Code"}, "price": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Unit price", "title": "Price"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount", "title": "Amount"}, "updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "sales_order_id", "updated_at"], "title": "SalesOrderLineResponse", "type": "object"}, "SalesOrderLineCreate": {"additionalProperties": false, "description": "Schema for creating a SalesOrderLine.", "properties": {"sales_order_id": {"description": "Parent sales order ID", "title": "Sales Order Id", "type": "integer"}, "netsuite_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite line ID", "title": "Netsuite Line Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code", "title": "Service Code"}, "price": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Unit price", "title": "Price"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount", "title": "Amount"}}, "required": ["sales_order_id"], "title": "SalesOrderLineCreate", "type": "object"}, "SalesOrderLineUpdate": {"additionalProperties": false, "description": "Schema for updating a SalesOrderLine.", "properties": {"netsuite_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite line ID", "title": "Netsuite Line Id"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service code", "title": "Service Code"}, "price": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Unit price", "title": "Price"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount", "title": "Amount"}}, "title": "SalesOrderLineUpdate", "type": "object"}, "SalesInvoiceQueryParams": {"additionalProperties": false, "description": "Query parameters for sales invoices endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sales order ID", "title": "Sales Order Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}}, "title": "SalesInvoiceQueryParams", "type": "object"}, "SalesInvoiceResponse": {"additionalProperties": false, "description": "Schema for SalesInvoice response.", "properties": {"id": {"description": "Invoice ID", "title": "Id", "type": "integer"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order ID", "title": "Sales Order Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "netsuite_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite invoice ID", "title": "Netsuite Invoice Id"}, "invoice_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice date", "title": "Invoice Date"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice status", "title": "Status"}, "due_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Due date", "title": "Due Date"}, "invoice_final_sent": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the final invoice has been sent", "title": "Invoice Final Sent"}, "transaction_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NetSuite transaction number (tranId)", "title": "Transaction Number"}, "updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "updated_at"], "title": "SalesInvoiceResponse", "type": "object"}, "SalesInvoiceCreate": {"additionalProperties": false, "description": "Schema for creating a SalesInvoice.", "properties": {"sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order ID", "title": "Sales Order Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "netsuite_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite invoice ID", "title": "Netsuite Invoice Id"}, "invoice_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice date (YYYY-MM-DD)", "title": "Invoice Date"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice status", "title": "Status"}, "due_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Due date (YYYY-MM-DD)", "title": "Due Date"}, "invoice_final_sent": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the final invoice has been sent", "title": "Invoice Final Sent"}}, "title": "SalesInvoiceCreate", "type": "object"}, "SalesInvoiceUpdate": {"additionalProperties": false, "description": "Schema for updating a SalesInvoice.", "properties": {"sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order ID", "title": "Sales Order Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "netsuite_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite invoice ID", "title": "Netsuite Invoice Id"}, "invoice_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice date (YYYY-MM-DD)", "title": "Invoice Date"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Invoice status", "title": "Status"}, "due_date": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Due date (YYYY-MM-DD)", "title": "Due Date"}, "invoice_final_sent": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Whether the final invoice has been sent", "title": "Invoice Final Sent"}}, "title": "SalesInvoiceUpdate", "type": "object"}, "ServiceChargeQueryParams": {"additionalProperties": false, "description": "Query parameters for service charges endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by sales order ID", "title": "Sales Order Id"}, "billing_statement_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by billing statement ID", "title": "Billing Statement Id"}, "source_system": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by source system", "title": "Source System"}}, "title": "ServiceChargeQueryParams", "type": "object"}, "ServiceChargeResponse": {"additionalProperties": false, "description": "Schema for ServiceCharge response.", "properties": {"id": {"description": "Charge ID", "title": "Id", "type": "integer"}, "charge_date": {"description": "Charge date", "format": "date", "title": "Charge Date", "type": "string"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Dispatch service order line ID", "title": "Service Order Line Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID", "title": "Robot Set Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "source_system": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Source system", "title": "Source System"}, "price": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Unit price", "title": "Price"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount", "title": "Amount"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "netsuite_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NetSuite status", "title": "Netsuite Status"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order ID", "title": "Sales Order Id"}, "sales_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order line ID", "title": "Sales Order Line Id"}, "sales_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales invoice ID", "title": "Sales Invoice Id"}, "netsuite_transaction_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite transaction ID", "title": "Netsuite Transaction Id"}, "billing_statement_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Billing statement ID", "title": "Billing Statement Id"}, "updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "charge_date", "updated_at"], "title": "ServiceChargeResponse", "type": "object"}, "ServiceChargeCreate": {"additionalProperties": false, "description": "Schema for creating a ServiceCharge.", "properties": {"charge_date": {"description": "Charge date (YYYY-MM-DD)", "format": "date", "title": "Charge Date", "type": "string"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Dispatch service order line ID", "title": "Service Order Line Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID", "title": "Robot Set Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "source_system": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Source system (OPSHUB, NETSUITE)", "title": "Source System"}, "price": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Unit price", "title": "Price"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount", "title": "Amount"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "netsuite_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NetSuite status", "title": "Netsuite Status"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order ID", "title": "Sales Order Id"}, "sales_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order line ID", "title": "Sales Order Line Id"}, "sales_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales invoice ID", "title": "Sales Invoice Id"}, "netsuite_transaction_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite transaction ID", "title": "Netsuite Transaction Id"}, "billing_statement_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Billing statement ID", "title": "Billing Statement Id"}}, "required": ["charge_date"], "title": "ServiceChargeCreate", "type": "object"}, "ServiceChargeUpdate": {"additionalProperties": false, "description": "Schema for updating a ServiceCharge.", "properties": {"charge_date": {"description": "Charge date (YYYY-MM-DD)", "format": "date", "title": "Charge Date", "type": "string"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Dispatch service order line ID", "title": "Service Order Line Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Robot set ID", "title": "Robot Set Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Service ID", "title": "Service Id"}, "currency_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO 4217 currency code", "title": "Currency Code"}, "source_system": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Source system (OPSHUB, NETSUITE)", "title": "Source System"}, "price": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Unit price", "title": "Price"}, "quantity": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Quantity", "title": "Quantity"}, "amount": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "description": "Total amount", "title": "Amount"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Description", "title": "Description"}, "netsuite_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NetSuite status", "title": "Netsuite Status"}, "sales_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order ID", "title": "Sales Order Id"}, "sales_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales order line ID", "title": "Sales Order Line Id"}, "sales_invoice_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Sales invoice ID", "title": "Sales Invoice Id"}, "netsuite_transaction_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "NetSuite transaction ID", "title": "Netsuite Transaction Id"}, "billing_statement_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Billing statement ID", "title": "Billing Statement Id"}}, "required": ["charge_date"], "title": "ServiceChargeUpdate", "type": "object"}, "BillingStatementQueryParams": {"additionalProperties": false, "description": "Query parameters for billing statements endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status", "title": "Status"}, "billing_period": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by billing period", "title": "Billing Period"}}, "title": "BillingStatementQueryParams", "type": "object"}, "BillingStatementResponse": {"additionalProperties": false, "description": "Schema for BillingStatement response.", "properties": {"id": {"description": "Billing statement ID", "title": "Id", "type": "integer"}, "project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "date_from": {"description": "Period start date", "format": "date", "title": "Date From", "type": "string"}, "date_to": {"description": "Period end date", "format": "date", "title": "Date To", "type": "string"}, "billing_period": {"description": "Billing period", "title": "Billing Period", "type": "string"}, "status": {"description": "Status", "title": "Status", "type": "string"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "project_id", "customer_id", "date_from", "date_to", "billing_period", "status", "created_at", "updated_at"], "title": "BillingStatementResponse", "type": "object"}, "BillingStatementCreate": {"additionalProperties": false, "description": "Schema for creating a BillingStatement.", "properties": {"project_id": {"description": "Project ID", "title": "Project Id", "type": "integer"}, "customer_id": {"description": "Customer ID", "title": "Customer Id", "type": "integer"}, "date_from": {"description": "Period start date (YYYY-MM-DD)", "title": "Date From", "type": "string"}, "date_to": {"description": "Period end date (YYYY-MM-DD)", "title": "Date To", "type": "string"}, "billing_period": {"description": "Billing period (WEEK, MONTH)", "title": "Billing Period", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status (defaults to DRAFT)", "title": "Status"}}, "required": ["project_id", "customer_id", "date_from", "date_to", "billing_period"], "title": "BillingStatementCreate", "type": "object"}, "BillingStatementUpdate": {"additionalProperties": false, "description": "Schema for updating a BillingStatement.", "properties": {"project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Project ID", "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Customer ID", "title": "Customer Id"}, "date_from": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Period start date (YYYY-MM-DD)", "title": "Date From"}, "date_to": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Period end date (YYYY-MM-DD)", "title": "Date To"}, "billing_period": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Billing period (WEEK, MONTH)", "title": "Billing Period"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Status", "title": "Status"}}, "title": "BillingStatementUpdate", "type": "object"}, "NoteQueryParams": {"additionalProperties": false, "description": "Query parameters for notes endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "entity_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by entity type", "title": "Entity Name"}, "entity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by entity ID", "title": "Entity Id"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by internal flag", "title": "Is Internal"}}, "title": "NoteQueryParams", "type": "object"}, "NoteResponse": {"additionalProperties": false, "description": "Schema for Note response.", "properties": {"id": {"description": "Note ID", "title": "Id", "type": "integer"}, "entity_name": {"description": "Entity type", "title": "Entity Name", "type": "string"}, "entity_id": {"description": "ID of the related entity", "title": "Entity Id", "type": "integer"}, "content": {"description": "Note content", "title": "Content", "type": "string"}, "is_internal": {"description": "Internal note hidden from customers", "title": "Is Internal", "type": "boolean"}, "created_by": {"anyOf": [{"$ref": "#/components/schemas/UserObject"}, {"type": "null"}], "description": "Note author"}, "created_at": {"description": "Creation timestamp", "format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "entity_name", "entity_id", "content", "is_internal", "created_at", "updated_at"], "title": "NoteResponse", "type": "object"}, "NoteCreate": {"additionalProperties": false, "description": "Schema for creating a Note.", "properties": {"entity_name": {"description": "Entity type (e.g. service_charge, billing_statement)", "title": "Entity Name", "type": "string"}, "entity_id": {"description": "ID of the related entity", "title": "Entity Id", "type": "integer"}, "content": {"description": "Note content", "title": "Content", "type": "string"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "default": false, "description": "Internal note hidden from customers", "title": "Is Internal"}}, "required": ["entity_name", "entity_id", "content"], "title": "NoteCreate", "type": "object"}, "NoteUpdate": {"additionalProperties": false, "description": "Schema for updating a Note.", "properties": {"content": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Note content", "title": "Content"}, "is_internal": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Internal note hidden from customers", "title": "Is Internal"}}, "title": "NoteUpdate", "type": "object"}, "FileList": {"additionalProperties": false, "description": "Response schema for listing all files.", "properties": {"files": {"description": "List of all files in the system.", "items": {"$ref": "#/components/schemas/FileAttachment"}, "title": "Files", "type": "array"}}, "required": ["files"], "title": "FileList", "type": "object"}, "CoveragePublishedPayload": {"description": "Payload WMS sends when a roster layer is published.\n\nproject_codes is the union of every project_code with at least one\nassignment in the published layer's date range \u2014 WMS doesn't diff\nagainst the prior snapshot. Our handler is idempotent so receiving\nuntouched codes is harmless. The ``Literal`` on ``event`` rejects\nany other event type at the API boundary, before fan-out runs.\n\nUses plain ``ninja.Schema`` (not the ``extra='forbid'`` REST base) on\npurpose: this is an inbound webhook from an external system, so unknown\nfields WMS may add later are ignored rather than 422-rejected \u2014 the\nintegration stays forward-compatible without a lock-step deploy.", "properties": {"event": {"const": "coverage.published", "enum": ["coverage.published"], "title": "Event", "type": "string"}, "layer_id": {"title": "Layer Id", "type": "integer"}, "project_codes": {"items": {"type": "string"}, "title": "Project Codes", "type": "array"}, "date_from": {"format": "date", "title": "Date From", "type": "string"}, "date_to": {"format": "date", "title": "Date To", "type": "string"}, "published_at": {"format": "date-time", "title": "Published At", "type": "string"}, "delivery_id": {"title": "Delivery Id", "type": "string"}}, "required": ["event", "layer_id", "project_codes", "date_from", "date_to", "published_at", "delivery_id"], "title": "CoveragePublishedPayload", "type": "object"}, "TaskUpdatedPayload": {"description": "Payload the travel app sends when one of its travel requests changes.\n\nUses plain ``ninja.Schema`` (not the ``extra='forbid'`` REST base) on\npurpose: this is an inbound webhook from an external system, so unknown\nfields the travel app may add later are ignored rather than 422-rejected \u2014\nthe integration stays forward-compatible without a lock-step deploy.\n\nOnly ``project_code`` is consumed \u2014 it identifies which project to recompute\n(the recompute re-reads the Travel API by project code). ``reference`` and\n``event`` are accepted for logging/observability only.", "properties": {"project_code": {"title": "Project Code", "type": "string"}, "reference": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Reference"}, "event": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Event"}}, "required": ["project_code"], "title": "TaskUpdatedPayload", "type": "object"}, "_NotePayload": {"additionalProperties": false, "properties": {"text": {"title": "Text", "type": "string"}}, "required": ["text"], "title": "_NotePayload", "type": "object"}, "SalesOrdersByCodeGET": {"additionalProperties": false, "description": "By project code.", "properties": {"project_code": {"title": "Project Code", "type": "string"}}, "required": ["project_code"], "title": "SalesOrdersByCodeGET", "type": "object"}, "Subsidiary": {"additionalProperties": false, "description": "Subsidiary", "properties": {"id": {"description": "NetSuite ID of the subsidiary", "title": "Id", "type": "integer"}, "name": {"description": "Name of the subsidiary", "title": "Name", "type": "string"}, "country": {"description": "Country of the subsidiary", "title": "Country", "type": "string"}, "iselimination": {"description": "Is elimination", "title": "Iselimination", "type": "boolean"}, "currency": {"description": "Currency of the subsidiary", "title": "Currency", "type": "string"}, "parent": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Parent subsidiary of this subsidiary", "title": "Parent"}}, "required": ["id", "name", "country", "iselimination", "currency"], "title": "Subsidiary", "type": "object"}, "SchedulerJob": {"additionalProperties": false, "description": "Schema for scheduler job details.", "properties": {"name": {"title": "Name", "type": "string"}, "next_run_time": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Next Run Time"}}, "required": ["name", "next_run_time"], "title": "SchedulerJob", "type": "object"}, "SchedulerJobList": {"additionalProperties": false, "description": "Schema for list of scheduler jobs.", "properties": {"jobs": {"items": {"$ref": "#/components/schemas/SchedulerJob"}, "title": "Jobs", "type": "array"}}, "required": ["jobs"], "title": "SchedulerJobList", "type": "object"}, "SendEmailResponse": {"additionalProperties": false, "description": "Response for a successful (or dev-mode-skipped) `/email` call.", "properties": {"success": {"description": "Whether the email was queued for sending", "title": "Success", "type": "boolean"}, "tracking_id": {"anyOf": [{"format": "uuid", "type": "string"}, {"type": "null"}], "description": "Id to poll `/email/{tracking_id}/status` with. Null when success is false.", "title": "Tracking Id"}}, "required": ["success"], "title": "SendEmailResponse", "type": "object"}, "EmailContext": {"additionalProperties": false, "description": "Define the template context for an email.\n\nEmail context defines which template and with what variables are to be\nsent.", "properties": {"template": {"$ref": "#/components/schemas/EmailTemplateNames", "description": "Template name without file extension"}, "variables": {"description": "Key-value data for template placeholders", "title": "Variables", "type": "object"}}, "required": ["template"], "title": "EmailContext", "type": "object"}, "EmailRequest": {"additionalProperties": false, "description": "Incoming payload for sending a templated email.", "properties": {"to": {"description": "List of recipient email addresses", "examples": [["user@example.com", "other@example.com"], ["user@example.com"]], "items": {"format": "email", "type": "string"}, "title": "To", "type": "array"}, "cc": {"anyOf": [{"items": {"format": "email", "type": "string"}, "type": "array"}, {"type": "null"}], "description": "List of CC recipient email addresses", "examples": [["cc1@example.com", "cc2@example.com"]], "title": "Cc"}, "bcc": {"anyOf": [{"items": {"format": "email", "type": "string"}, "type": "array"}, {"type": "null"}], "description": "List of BCC recipient email addresses (audit / silent copy)", "examples": [["audit@example.com"]], "title": "Bcc"}, "reply_to": {"anyOf": [{"format": "email", "type": "string"}, {"type": "null"}], "description": "Address replies should be routed to. Useful when the SMTP From is a no-reply mailbox but you want client replies to land on a specific human address.", "examples": ["pm@example.com"], "title": "Reply To"}, "subject": {"description": "Email subject line", "title": "Subject", "type": "string"}, "attachments": {"anyOf": [{"items": {"type": "object"}, "type": "array"}, {"type": "null"}], "description": "Inline attachments: [{filename, content_base64, content_type}]", "examples": [[{"content_base64": "JVBERi\u2026", "content_type": "application/pdf", "filename": "x.pdf"}]], "title": "Attachments"}, "context": {"$ref": "#/components/schemas/EmailContext", "description": "Template rendering configuration"}}, "required": ["to", "subject", "context"], "title": "EmailRequest", "type": "object"}, "EmailTemplateNames": {"description": "Definitions of available email templates.", "enum": ["builder.travelorder.technician", "builder.travelorder.teamlead", "builder.travelorder.supervisor", "builder.travelorder.pm-sales", "builder.travelorder.teamlead-reminder", "builder.travelorder.supervisor-action-required", "builder.travelorder.data-operator", "builder.travelorder.questionnaire-complete", "builder.travelorder.supervisor-questionnaire-complete", "builder.offer.required-approval", "builder.offer.watcher-require-approval-notification", "builder.offer.watcher-offer-notification", "builder.offer.offer-notification", "builder.prejob.submission-notification", "builder.rams.hse-review", "builder.rams.customer-review", "builder.rams.technician-signing", "builder.rams.rejected", "builder.rams.approved", "builder.team_request.dc-review", "builder.team_request.planner-handoff", "builder.team_request.verification-ready", "builder.team_request.slot-rejection", "builder.team_request.rejected", "builder.team_request.note-mention", "builder.rotation.approved", "builder.project_task.comment-mention", "builder.set_request.submitted", "builder.set_request.mro-ready", "builder.set_request.it-starlink", "builder.set_request.ready", "builder.set_request.picked-up", "builder.set_request.rejected", "builder.set_request.set-changed", "builder.set_request.ppe-prep", "builder.set_demob.detected", "builder.set_demob.it-starlink", "builder.set_demob.mro-arrival", "datatools.payrollweeklyreport.weekly-report", "portal.feedback-form", "portal.accept-invitation", "auth.create-user", "auth.reset-password", "po-center.po-extension.internal-70", "po-center.po-extension.internal-80", "po-center.po-extension.internal-90", "po-center.po-extension.internal-100-active", "po-center.po-extension.internal-100-invoices", "po-center.po-extension.client-70", "po-center.po-extension.client-80", "po-center.po-extension.client-90", "po-center.po-extension.client-active", "po-center.po-extension.client-invoices", "po-center.digest.missing-pos", "po-center.digest.no-pm", "po-center.draft-charges.heads-up", "po-center.draft-charges.client", "po-center.overdue-invoice.heads-up", "po-center.overdue-invoice.client"], "title": "EmailTemplateNames", "type": "string"}, "SentEmailStatusResponse": {"additionalProperties": false, "description": "Response for `GET /email/{tracking_id}/status`.", "properties": {"status": {"description": "One of SENT, OPENED, BOUNCED", "title": "Status", "type": "string"}, "sent_at": {"description": "ISO timestamp the email was queued", "title": "Sent At", "type": "string"}, "status_changed_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ISO timestamp of the last status transition, if any", "title": "Status Changed At"}}, "required": ["status", "sent_at"], "title": "SentEmailStatusResponse", "type": "object"}, "GlobalDeviationsFiltersQueryParams": {"additionalProperties": false, "description": "Query parameters for GET /deviations/filters.", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}}, "title": "GlobalDeviationsFiltersQueryParams", "type": "object"}, "CountryFilter": {"additionalProperties": false, "description": "Country filter item with code and name.", "properties": {"code": {"description": "Country code (alpha-2)", "title": "Code", "type": "string"}, "name": {"description": "Country name", "title": "Name", "type": "string"}}, "required": ["code", "name"], "title": "CountryFilter", "type": "object"}, "GlobalDeviationsFilters": {"additionalProperties": false, "description": "Response schema for GET /deviations/filters.", "properties": {"project_codes": {"description": "All unique project codes", "items": {"type": "string"}, "title": "Project Codes", "type": "array"}, "country_codes": {"description": "All unique countries with code and name", "items": {"$ref": "#/components/schemas/CountryFilter"}, "title": "Country Codes", "type": "array"}, "regions": {"description": "All unique region names", "items": {"type": "string"}, "title": "Regions", "type": "array"}}, "title": "GlobalDeviationsFilters", "type": "object"}, "GlobalDeviationsSummaryQueryParams": {"additionalProperties": false, "description": "Query parameters for GET /deviations/summary.", "properties": {"period_type": {"allOf": [{"description": "Global period type enumeration (weekly or monthly).", "enum": ["weekly", "monthly"], "title": "GlobalPeriodTypeEnum", "type": "string"}], "default": "weekly", "description": "Period type: 'weekly' (default) or 'monthly'"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Partial match search on project code (case-insensitive)", "title": "Search"}, "project_codes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by exact project codes (comma-separated)", "title": "Project Codes"}, "country_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by country codes (comma-separated alpha-2)", "title": "Country Code"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated)", "title": "Region"}, "filter_currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency for financial filters (EUR, USD, or AUD)", "title": "Filter Currency"}, "fixed_planned_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned value", "title": "Fixed Planned Min"}, "fixed_planned_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned value", "title": "Fixed Planned Max"}, "actual_planned_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned value", "title": "Actual Planned Min"}, "actual_planned_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned value", "title": "Actual Planned Max"}, "amount_charged_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum amount charged", "title": "Amount Charged Min"}, "amount_charged_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum amount charged", "title": "Amount Charged Max"}, "deviation_from_actual_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from actual", "title": "Deviation From Actual Min"}, "deviation_from_actual_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from actual", "title": "Deviation From Actual Max"}, "deviation_from_fixed_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from fixed", "title": "Deviation From Fixed Min"}, "deviation_from_fixed_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from fixed", "title": "Deviation From Fixed Max"}}, "title": "GlobalDeviationsSummaryQueryParams", "type": "object"}, "GlobalPeriodTypeEnum": {"description": "Global period type enumeration (weekly or monthly).", "enum": ["weekly", "monthly"], "title": "GlobalPeriodTypeEnum", "type": "string"}, "CurrencyAmounts": {"additionalProperties": false, "description": "Financial amounts in multiple currencies.", "properties": {"EUR": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Amount in EUR", "title": "Eur"}, "AUD": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Amount in AUD", "title": "Aud"}, "USD": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Amount in USD", "title": "Usd"}}, "title": "CurrencyAmounts", "type": "object"}, "GlobalDeviationsSummary": {"additionalProperties": false, "description": "Summary schema for global deviations aggregated data.", "properties": {"project_count": {"description": "Total number of unique projects", "title": "Project Count", "type": "integer"}, "fixed_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total fixed planned value across all filtered rows"}, "actual_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total actual planned value across all filtered rows"}, "amount_charged": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total amount charged across all filtered rows"}, "deviation_from_actual": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total deviation from actual across all filtered rows"}, "deviation_from_fixed": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total deviation from fixed across all filtered rows"}}, "required": ["project_count", "fixed_planned", "actual_planned", "amount_charged", "deviation_from_actual", "deviation_from_fixed"], "title": "GlobalDeviationsSummary", "type": "object"}, "ProjectDeviationsFiltersQueryParams": {"additionalProperties": false, "description": "Query parameters for GET /deviations/{project_id}/filters.", "properties": {"start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}}, "title": "ProjectDeviationsFiltersQueryParams", "type": "object"}, "ProjectDeviationsFilters": {"additionalProperties": false, "description": "Response schema for GET /deviations/{project_id}/filters.", "properties": {"robotic_sets": {"description": "All unique robotic sets", "items": {"type": "string"}, "title": "Robotic Sets", "type": "array"}, "service_codes": {"description": "All unique service codes", "items": {"type": "string"}, "title": "Service Codes", "type": "array"}}, "title": "ProjectDeviationsFilters", "type": "object"}, "PeriodTypeEnum": {"description": "Period type enumeration.", "enum": ["daily", "weekly"], "title": "PeriodTypeEnum", "type": "string"}, "ProjectDeviationsSummaryQueryParams": {"additionalProperties": false, "description": "Query parameters for GET /deviations/{project_id}/summary.", "properties": {"period_type": {"allOf": [{"description": "Period type enumeration.", "enum": ["daily", "weekly"], "title": "PeriodTypeEnum", "type": "string"}], "default": "daily", "description": "Period type: 'daily' (default) or 'weekly'"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "robotic_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robotic set", "title": "Robotic Set"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}}, "title": "ProjectDeviationsSummaryQueryParams", "type": "object"}, "ProjectDeviationsSummary": {"additionalProperties": false, "description": "Summary schema for project-specific deviations aggregated data.", "properties": {"project_id": {"description": "Project ID (UUID)", "title": "Project Id", "type": "string"}, "project_code": {"description": "Project code", "title": "Project Code", "type": "string"}, "row_count": {"description": "Total number of rows matching filters", "title": "Row Count", "type": "integer"}, "robotic_set_count": {"description": "Number of unique robotic sets", "title": "Robotic Set Count", "type": "integer"}, "fixed_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total fixed planned value across all filtered rows"}, "actual_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total actual planned value across all filtered rows"}, "amount_charged": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total amount charged across all filtered rows"}, "deviation_from_actual": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total deviation from actual across all filtered rows"}, "deviation_from_fixed": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Total deviation from fixed across all filtered rows"}}, "required": ["project_id", "project_code", "row_count", "robotic_set_count", "fixed_planned", "actual_planned", "amount_charged", "deviation_from_actual", "deviation_from_fixed"], "title": "ProjectDeviationsSummary", "type": "object"}, "DeviationsQueryParams": {"additionalProperties": false, "description": "Query parameters for GET /deviations/{project_id}.", "properties": {"period_type": {"allOf": [{"description": "Period type enumeration.", "enum": ["daily", "weekly"], "title": "PeriodTypeEnum", "type": "string"}], "default": "daily", "description": "Period type: 'daily' (default) or 'weekly'"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "robotic_set": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by robotic set", "title": "Robotic Set"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service code", "title": "Service Code"}, "page": {"default": 1, "description": "Page number for pagination", "title": "Page", "type": "integer"}, "page_size": {"default": 10, "description": "Number of items per page", "title": "Page Size", "type": "integer"}, "format": {"anyOf": [{"$ref": "#/components/schemas/ExportFormat"}, {"type": "null"}], "description": "Export format: 'csv' or 'xlsx'. If not provided, returns JSON."}}, "title": "DeviationsQueryParams", "type": "object"}, "ExportFormat": {"description": "Export format options.", "enum": ["csv", "xlsx"], "title": "ExportFormat", "type": "string"}, "DeviationCategoryEnum": {"description": "Deviation category enumeration.\n\nInternal categories (fault_side = Internal):\n- Set Readiness, Rotation, Missing reports, Low performance,\n Sales, Planning, Health & Safety\n\nExternal categories (fault_side = External):\n- Customer, Weather, Previous project delay", "enum": ["Set Readiness", "Rotation", "Missing reports", "Low performance", "Sales", "Planning", "Health & Safety", "Customer", "Weather", "Previous project delay"], "title": "DeviationCategoryEnum", "type": "string"}, "DeviationRow": {"additionalProperties": false, "description": "Single deviation row in response (daily or weekly).", "properties": {"id": {"description": "Unique identifier for this deviation row", "title": "Id", "type": "string"}, "period": {"$ref": "#/components/schemas/Period", "description": "Period information"}, "robotic_set": {"description": "Robotic set identifier", "title": "Robotic Set", "type": "string"}, "service_codes": {"description": "USN service codes array", "items": {"type": "string"}, "title": "Service Codes", "type": "array"}, "fixed_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Fixed planned value (snapshot from month start)"}, "actual_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Actual planned value (current state)"}, "amount_charged": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Sum of charges (daily or aggregated weekly)"}, "deviation_from_actual": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Deviation from actual planned (charged - actual_planned)"}, "deviation_from_fixed": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Deviation from fixed planned (charged - fixed_planned)"}, "deviation_between_fixed_and_actual": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Difference between fixed and actual planned (fixed - actual)"}, "deviation": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "DEPRECATED: Use deviation_from_actual. (charged - actual_planned)"}, "fault_side": {"description": "Fault sides inferred from categories (Internal/External)", "items": {"$ref": "#/components/schemas/FaultSideEnum"}, "title": "Fault Side", "type": "array"}, "category": {"description": "Deviation categories (user editable)", "items": {"$ref": "#/components/schemas/DeviationCategoryEnum"}, "title": "Category", "type": "array"}, "comment": {"default": "", "description": "User comment (user editable)", "title": "Comment", "type": "string"}, "updated_by": {"default": "", "description": "First name + last name of user who last edited", "title": "Updated By", "type": "string"}, "is_locked": {"description": "Whether this row can be edited based on locking rules", "title": "Is Locked", "type": "boolean"}}, "required": ["id", "period", "robotic_set", "fixed_planned", "actual_planned", "amount_charged", "deviation_from_actual", "deviation_from_fixed", "deviation_between_fixed_and_actual", "deviation", "is_locked"], "title": "DeviationRow", "type": "object"}, "DeviationsListResponse": {"additionalProperties": false, "description": "Response schema for GET /deviations/{project_id}.", "properties": {"project_id": {"description": "Project ID (UUID)", "title": "Project Id", "type": "string"}, "project_code": {"description": "Project code", "title": "Project Code", "type": "string"}, "rows": {"description": "List of deviation rows", "items": {"$ref": "#/components/schemas/DeviationRow"}, "title": "Rows", "type": "array"}, "total_count": {"description": "Total number of rows (before pagination)", "title": "Total Count", "type": "integer"}, "page": {"description": "Current page number", "title": "Page", "type": "integer"}, "page_size": {"description": "Number of items per page", "title": "Page Size", "type": "integer"}}, "required": ["project_id", "project_code", "total_count", "page", "page_size"], "title": "DeviationsListResponse", "type": "object"}, "FaultSideEnum": {"description": "Fault side enumeration.", "enum": ["Internal", "External"], "title": "FaultSideEnum", "type": "string"}, "Period": {"additionalProperties": false, "description": "Period information for deviation rows.", "properties": {"type": {"$ref": "#/components/schemas/PeriodTypeEnum", "description": "Period type (daily or weekly)"}, "start_date": {"description": "Start date (YYYY-MM-DD)", "title": "Start Date", "type": "string"}, "end_date": {"description": "End date (YYYY-MM-DD)", "title": "End Date", "type": "string"}, "week_number": {"description": "ISO week number (1-53)", "title": "Week Number", "type": "integer"}, "year": {"description": "ISO year for the week", "title": "Year", "type": "integer"}}, "required": ["type", "start_date", "end_date", "week_number", "year"], "title": "Period", "type": "object"}, "DeviationsPatchResponse": {"additionalProperties": false, "description": "Response schema for PATCH /deviations/{project_id}.", "properties": {"updated_count": {"description": "Number of rows successfully updated", "title": "Updated Count", "type": "integer"}, "failed_count": {"description": "Number of rows that failed to update", "title": "Failed Count", "type": "integer"}, "errors": {"description": "List of errors for failed updates", "items": {"type": "object"}, "title": "Errors", "type": "array"}}, "required": ["updated_count", "failed_count"], "title": "DeviationsPatchResponse", "type": "object"}, "DeviationUpdateItem": {"additionalProperties": false, "description": "Single deviation update in PATCH request.", "properties": {"id": {"description": "Unique identifier for the deviation row", "title": "Id", "type": "string"}, "period_type": {"allOf": [{"$ref": "#/components/schemas/PeriodTypeEnum"}], "default": "daily", "description": "Period type (daily or weekly) to identify which entity to update"}, "category": {"anyOf": [{"items": {"$ref": "#/components/schemas/DeviationCategoryEnum"}, "type": "array"}, {"type": "null"}], "description": "New deviation categories array (null to keep existing, empty to clear). Not allowed for weekly type.", "title": "Category"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "New comment (null to keep existing)", "title": "Comment"}}, "required": ["id"], "title": "DeviationUpdateItem", "type": "object"}, "GlobalDeviationsQueryParams": {"additionalProperties": false, "description": "Query parameters for GET /deviations.", "properties": {"period_type": {"allOf": [{"description": "Global period type enumeration (weekly or monthly).", "enum": ["weekly", "monthly"], "title": "GlobalPeriodTypeEnum", "type": "string"}], "default": "weekly", "description": "Period type: 'weekly' (default) or 'monthly'"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by start date (YYYY-MM-DD)", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter by end date (YYYY-MM-DD)", "title": "End Date"}, "search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Partial match search on project code (case-insensitive)", "title": "Search"}, "project_codes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by exact project codes (comma-separated, e.g. 'EBUS-4885,GEFI-4916')", "title": "Project Codes"}, "country_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by country codes (comma-separated alpha-2, e.g. 'BE,DE,FR')", "title": "Country Code"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by regions (comma-separated, e.g. 'Europe,North America')", "title": "Region"}, "filter_currency": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Currency for financial filters (EUR, USD, or AUD)", "title": "Filter Currency"}, "fixed_planned_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum fixed planned value", "title": "Fixed Planned Min"}, "fixed_planned_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum fixed planned value", "title": "Fixed Planned Max"}, "actual_planned_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum actual planned value", "title": "Actual Planned Min"}, "actual_planned_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum actual planned value", "title": "Actual Planned Max"}, "amount_charged_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum amount charged", "title": "Amount Charged Min"}, "amount_charged_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum amount charged", "title": "Amount Charged Max"}, "deviation_from_actual_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from actual", "title": "Deviation From Actual Min"}, "deviation_from_actual_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from actual", "title": "Deviation From Actual Max"}, "deviation_from_fixed_min": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Minimum deviation from fixed", "title": "Deviation From Fixed Min"}, "deviation_from_fixed_max": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "Maximum deviation from fixed", "title": "Deviation From Fixed Max"}, "page": {"default": 1, "description": "Page number for pagination", "title": "Page", "type": "integer"}, "page_size": {"default": 50, "description": "Number of items per page", "title": "Page Size", "type": "integer"}, "format": {"anyOf": [{"$ref": "#/components/schemas/ExportFormat"}, {"type": "null"}], "description": "Export format: 'csv' or 'xlsx'. If not provided, returns JSON."}}, "title": "GlobalDeviationsQueryParams", "type": "object"}, "DeviationCountry": {"additionalProperties": false, "description": "Country information for deviations.", "properties": {"code": {"description": "Country code in alpha-2", "title": "Code", "type": "string"}, "name": {"description": "Human readable country name", "title": "Name", "type": "string"}, "region": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Custom region name a country belongs to", "title": "Region"}}, "required": ["code", "name"], "title": "DeviationCountry", "type": "object"}, "GlobalDeviationRow": {"additionalProperties": false, "description": "Single row in global deviations response (one row per project per period).", "properties": {"id": {"description": "Unique identifier for this global deviation row", "title": "Id", "type": "string"}, "period": {"$ref": "#/components/schemas/GlobalPeriod", "description": "Period information"}, "project_id": {"description": "Project ID (UUID)", "title": "Project Id", "type": "string"}, "project_code": {"description": "Project code", "title": "Project Code", "type": "string"}, "country": {"anyOf": [{"$ref": "#/components/schemas/DeviationCountry"}, {"type": "null"}], "description": "Country information"}, "robotic_sets": {"description": "All robotic sets for this project/period", "items": {"type": "string"}, "title": "Robotic Sets", "type": "array"}, "service_codes": {"description": "All service codes for this project/period", "items": {"type": "string"}, "title": "Service Codes", "type": "array"}, "fixed_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Aggregated fixed planned value (snapshot from month start)"}, "actual_planned": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Aggregated actual planned value (current state)"}, "amount_charged": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Aggregated sum of charges for the period"}, "deviation_from_actual": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Deviation from actual planned (charged - actual_planned)"}, "deviation_from_fixed": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Deviation from fixed planned (charged - fixed_planned)"}, "deviation_between_fixed_and_actual": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "Difference between fixed and actual planned (fixed - actual)"}, "deviation": {"$ref": "#/components/schemas/CurrencyAmounts", "description": "DEPRECATED: Use deviation_from_actual. (charged - actual_planned)"}, "fault_side": {"description": "Unique fault sides from all deviations in the period", "items": {"$ref": "#/components/schemas/FaultSideEnum"}, "title": "Fault Side", "type": "array"}, "categories": {"description": "Unique categories from all deviations in the period", "items": {"$ref": "#/components/schemas/DeviationCategoryEnum"}, "title": "Categories", "type": "array"}, "comment": {"default": "", "description": "Global comment for this period", "title": "Comment", "type": "string"}, "updated_by": {"default": "", "description": "User who last updated the comment", "title": "Updated By", "type": "string"}, "is_locked": {"description": "Whether this row can be edited based on locking rules", "title": "Is Locked", "type": "boolean"}}, "required": ["id", "period", "project_id", "project_code", "fixed_planned", "actual_planned", "amount_charged", "deviation_from_actual", "deviation_from_fixed", "deviation_between_fixed_and_actual", "deviation", "is_locked"], "title": "GlobalDeviationRow", "type": "object"}, "GlobalDeviationsListResponse": {"additionalProperties": false, "description": "Response schema for GET /deviations.", "properties": {"rows": {"description": "List of global deviation rows", "items": {"$ref": "#/components/schemas/GlobalDeviationRow"}, "title": "Rows", "type": "array"}, "total_count": {"description": "Total number of rows (before pagination)", "title": "Total Count", "type": "integer"}, "page": {"description": "Current page number", "title": "Page", "type": "integer"}, "page_size": {"description": "Number of items per page", "title": "Page Size", "type": "integer"}}, "required": ["total_count", "page", "page_size"], "title": "GlobalDeviationsListResponse", "type": "object"}, "GlobalPeriod": {"additionalProperties": false, "description": "Period information for global deviation rows.", "properties": {"type": {"$ref": "#/components/schemas/GlobalPeriodTypeEnum", "description": "Period type (weekly or monthly)"}, "start_date": {"description": "Start date (YYYY-MM-DD)", "title": "Start Date", "type": "string"}, "end_date": {"description": "End date (YYYY-MM-DD)", "title": "End Date", "type": "string"}, "week_number": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ISO week number (1-53), only for weekly type", "title": "Week Number"}, "year": {"description": "Year", "title": "Year", "type": "integer"}, "month": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Month (1-12), only for monthly type", "title": "Month"}}, "required": ["type", "start_date", "end_date", "year"], "title": "GlobalPeriod", "type": "object"}, "GlobalDeviationUpdateItem": {"additionalProperties": false, "description": "Single global deviation update in PATCH request.", "properties": {"id": {"description": "Unique identifier for the global deviation row", "title": "Id", "type": "string"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "New comment (null to keep existing)", "title": "Comment"}}, "required": ["id"], "title": "GlobalDeviationUpdateItem", "type": "object"}, "UnifiedServices": {"additionalProperties": false, "description": "Schema for unified services response.", "properties": {"response": {"description": "HTML response with service types", "title": "Response", "type": "string"}}, "required": ["response"], "title": "UnifiedServices", "type": "object"}, "ServiceLineItemQuery": {"additionalProperties": false, "description": "Query params for service line items.", "properties": {"category": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service category name.", "title": "Category"}, "group": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by service group name.", "title": "Group"}, "service": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item is reported as service.", "title": "Service"}, "rat": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter by whether item is provided by RAT.", "title": "Rat"}}, "title": "ServiceLineItemQuery", "type": "object"}, "ServiceLineItem": {"additionalProperties": false, "description": "Schema for unified service line item.", "properties": {"code": {"description": "Service item code.", "title": "Code", "type": "string"}, "line_item": {"description": "Service item description.", "title": "Line Item", "type": "string"}, "category": {"description": "Service category name.", "title": "Category", "type": "string"}, "service_group": {"description": "Service group name.", "title": "Service Group", "type": "string"}, "rat_team": {"description": "Whether service is provided by RAT.", "title": "Rat Team", "type": "boolean"}, "reported_as_service": {"description": "Whether the item is a service.", "title": "Reported As Service", "type": "boolean"}}, "required": ["code", "line_item", "category", "service_group", "rat_team", "reported_as_service"], "title": "ServiceLineItem", "type": "object"}, "ServiceLineItemFull": {"additionalProperties": false, "description": "Full schema including all available fields for unified service line item.", "properties": {"code": {"description": "Service item code.", "title": "Code", "type": "string"}, "line_item": {"description": "Service item description.", "title": "Line Item", "type": "string"}, "category": {"description": "Service category name.", "title": "Category", "type": "string"}, "service_group": {"description": "Service group name.", "title": "Service Group", "type": "string"}, "rat_team": {"description": "Whether service is provided by RAT.", "title": "Rat Team", "type": "boolean"}, "reported_as_service": {"description": "Whether the item is a service.", "title": "Reported As Service", "type": "boolean"}, "unit_types": {"description": "List of pricing unit names compatible with this service item.", "items": {"type": "string"}, "title": "Unit Types", "type": "array"}}, "required": ["code", "line_item", "category", "service_group", "rat_team", "reported_as_service", "unit_types"], "title": "ServiceLineItemFull", "type": "object"}, "TurbineManufacturer": {"description": "Schema for turbine manufacturer.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "models_count": {"title": "Models Count", "type": "integer"}}, "required": ["id", "name", "models_count"], "title": "TurbineManufacturer", "type": "object"}, "TurbineManufacturerResponse": {"description": "Schema for turbine manufacturer list response.", "properties": {"items": {"items": {"$ref": "#/components/schemas/TurbineManufacturer"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "TurbineManufacturerResponse", "type": "object"}, "LegacyTurbineModel": {"description": "Schema for turbine model (legacy turbines API).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "manufacturer_id": {"title": "Manufacturer Id", "type": "integer"}}, "required": ["id", "name", "manufacturer_id"], "title": "LegacyTurbineModel", "type": "object"}, "LegacyTurbineModelResponse": {"description": "Schema for turbine model list response (legacy turbines API).", "properties": {"items": {"items": {"$ref": "#/components/schemas/LegacyTurbineModel"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "LegacyTurbineModelResponse", "type": "object"}, "RefreshResponse": {"description": "Schema for refresh data response.", "properties": {"manufacturers_count": {"title": "Manufacturers Count", "type": "integer"}, "models_count": {"title": "Models Count", "type": "integer"}}, "required": ["manufacturers_count", "models_count"], "title": "RefreshResponse", "type": "object"}, "BladeManufacturer": {"description": "Schema for blade manufacturer.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "BladeManufacturer", "type": "object"}, "BladeManufacturerResponse": {"description": "Schema for blade manufacturer list response.", "properties": {"items": {"items": {"$ref": "#/components/schemas/BladeManufacturer"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "BladeManufacturerResponse", "type": "object"}, "LegacyBladeModel": {"description": "Schema for blade model (legacy turbines API).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "manufacturer_id": {"title": "Manufacturer Id", "type": "integer"}}, "required": ["id", "name", "manufacturer_id"], "title": "LegacyBladeModel", "type": "object"}, "LegacyBladeModelResponse": {"description": "Schema for blade model list response (legacy turbines API).", "properties": {"items": {"items": {"$ref": "#/components/schemas/LegacyBladeModel"}, "title": "Items", "type": "array"}}, "required": ["items"], "title": "LegacyBladeModelResponse", "type": "object"}, "UpdateUserRole": {"additionalProperties": false, "description": "Schema for updating user role.", "properties": {"is_admin": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Admin"}, "is_pm": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Pm"}, "is_user": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is User"}}, "title": "UpdateUserRole", "type": "object"}, "CIRValidationIssueSchema": {"additionalProperties": false, "properties": {"anomaly_id": {"title": "Anomaly Id", "type": "integer"}, "blade_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Blade Position"}, "blade_id": {"title": "Blade Id", "type": "integer"}, "missing_fields": {"items": {"type": "string"}, "title": "Missing Fields", "type": "array"}}, "required": ["anomaly_id", "blade_position", "blade_id", "missing_fields"], "title": "CIRValidationIssueSchema", "type": "object"}, "CIRValidationResultSchema": {"additionalProperties": false, "properties": {"is_valid": {"title": "Is Valid", "type": "boolean"}, "issues": {"items": {"$ref": "#/components/schemas/CIRValidationIssueSchema"}, "title": "Issues", "type": "array"}}, "required": ["is_valid", "issues"], "title": "CIRValidationResultSchema", "type": "object"}, "CIRSubmissionStatusSchema": {"additionalProperties": false, "properties": {"has_been_submitted": {"title": "Has Been Submitted", "type": "boolean"}, "last_submission_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Last Submission Id"}, "last_submission_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Submission Status"}, "last_submitted_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Submitted At"}, "last_submitted_by_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Submitted By Name"}, "error_message": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error Message"}, "last_successful_sync_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Successful Sync At"}}, "required": ["has_been_submitted"], "title": "CIRSubmissionStatusSchema", "type": "object"}, "CIRSubmitResponseSchema": {"additionalProperties": false, "properties": {"submission_id": {"title": "Submission Id", "type": "integer"}, "status": {"title": "Status", "type": "string"}}, "required": ["submission_id", "status"], "title": "CIRSubmitResponseSchema", "type": "object"}, "AnomalyAIStatus": {"description": "AI status for anomalies.", "enum": ["NEW", "QUALIFIED", "UNQUALIFIED", "CONFIRMED", "REJECTED", "DUPLICATE"], "title": "AnomalyAIStatus", "type": "string"}, "AnomalyFileSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}}, "required": ["id", "url"], "title": "AnomalyFileSchema", "type": "object"}, "AnomalyRegisteredByType": {"description": "Registered by classification for anomalies.", "enum": ["AERONES", "AI", "CUSTOMER"], "title": "AnomalyRegisteredByType", "type": "string"}, "AnomalySchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "blade_id": {"title": "Blade Id", "type": "integer"}, "severity": {"enum": [0, 1, 2, 3, 4, 5], "title": "Severity", "type": "integer"}, "width": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Width"}, "max_distance": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Distance"}, "placement": {"enum": ["INTERNAL", "EXTERNAL"], "title": "Placement", "type": "string"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Side"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rib"}, "distance_to_root": {"title": "Distance To Root", "type": "number"}, "files": {"anyOf": [{"items": {"$ref": "#/components/schemas/AnomalyFileSchema"}, "type": "array"}, {"type": "null"}], "description": "List of files associated with the anomaly", "title": "Files"}, "coordinates": {"anyOf": [{"items": {"items": {"type": "integer"}, "type": "array"}, "type": "array"}, {"type": "null"}], "description": "List of coordinates representing the anomaly's location on the blade. Format: [[x1, y1], [x2, y2], ...]", "title": "Coordinates"}, "anomaly_major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Major Component Id"}, "anomaly_major_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Anomaly Major Component Name"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Component Id"}, "anomaly_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Anomaly Component Name"}, "anomaly_sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Sub Component Id"}, "anomaly_sub_component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Anomaly Sub Component Name"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Type Id"}, "anomaly_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Anomaly Type Name"}, "anomaly_sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Sub Type Id"}, "anomaly_sub_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Anomaly Sub Type Name"}, "anomaly_material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Material Id"}, "anomaly_material_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Anomaly Material Name"}, "cim_case_number": {"title": "Cim Case Number", "type": "integer"}, "registered_by": {"$ref": "#/components/schemas/AnomalyRegisteredByType", "description": "Who registered the anomaly: AERONES (operator), AI or CUSTOMER"}, "ai_status": {"anyOf": [{"$ref": "#/components/schemas/AnomalyAIStatus"}, {"type": "null"}], "description": "Reviewer state of the linked AI detection; null when the anomaly has no AI record"}}, "required": ["id", "blade_id", "severity", "width", "max_distance", "placement", "side", "rib", "distance_to_root", "anomaly_major_component_id", "anomaly_major_component_name", "anomaly_component_id", "anomaly_component_name", "anomaly_sub_component_id", "anomaly_sub_component_name", "anomaly_type_id", "anomaly_type_name", "anomaly_sub_type_id", "anomaly_sub_type_name", "anomaly_material_id", "anomaly_material_name", "cim_case_number", "registered_by"], "title": "AnomalySchema", "type": "object"}, "BladePhotoSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "cdn_base_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Base CDN URL of the directory holding this photo \u2014 same convention as the VIS inspection payload: build the final URL as f'{cdn_base_url}/{percent_encoded(name)}'.", "title": "Cdn Base Url"}}, "required": ["id", "name", "cdn_base_url"], "title": "BladePhotoSchema", "type": "object"}, "BladeSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "position": {"description": "Position of the blade on the turbine", "enum": ["A", "B", "C"], "title": "Position", "type": "string"}, "serial_number": {"description": "Serial number of the blade", "title": "Serial Number", "type": "string"}, "manufacturer": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Manufacturer of the blade", "title": "Manufacturer"}, "item_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Item number of the blade", "title": "Item Number"}, "blade_id_image_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "URL of the blade identification image", "title": "Blade Id Image Url"}, "root_chamber_photos": {"description": "Hand-taken root chamber photos (CIR photo set 1), no offset applied \u2014 not anomaly-linked, sourced from VIS's ROOT_PHOTOS section.", "items": {"$ref": "#/components/schemas/BladePhotoSchema"}, "title": "Root Chamber Photos", "type": "array"}, "ch2_photos": {"description": "Hand-taken chamber 2 photos (CIR photo set 2), no offset applied \u2014 not anomaly-linked. The inspection crawler cannot physically enter Chamber 2, so the app never generates a dedicated section for it: technicians upload CH2 photos by hand together with root chamber photos into VIS's ROOT_PHOTOS section, so this field mirrors root_chamber_photos exactly.", "items": {"$ref": "#/components/schemas/BladePhotoSchema"}, "title": "Ch2 Photos", "type": "array"}}, "required": ["id", "position", "serial_number", "manufacturer", "item_number", "blade_id_image_url"], "title": "BladeSchema", "type": "object"}, "TurbineSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "latitude": {"title": "Latitude", "type": "number"}, "longitude": {"title": "Longitude", "type": "number"}, "blades": {"items": {"$ref": "#/components/schemas/BladeSchema"}, "title": "Blades", "type": "array"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Serial number of the turbine", "title": "Serial Number"}}, "required": ["id", "latitude", "longitude", "blades", "serial_number"], "title": "TurbineSchema", "type": "object"}, "VestasCIRDataSchema": {"additionalProperties": false, "properties": {"service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}, "turbine": {"$ref": "#/components/schemas/TurbineSchema"}, "anomalies": {"items": {"$ref": "#/components/schemas/AnomalySchema"}, "title": "Anomalies", "type": "array"}, "inspection_date": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Inspection Date"}, "is_annual_inspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Annual Inspection"}, "work_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Work Order Number"}}, "required": ["service_order_line_id", "turbine", "anomalies", "inspection_date", "is_annual_inspection", "work_order_number"], "title": "VestasCIRDataSchema", "type": "object"}, "NordexActivityResourceSchema": {"additionalProperties": false, "properties": {"activity_id": {"description": "Join key for 'activities[].id'.", "title": "Activity Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Full Name"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "TECHNICIAN or ROBOT.", "title": "Resource Type"}, "is_lead": {"title": "Is Lead", "type": "boolean"}}, "required": ["activity_id", "full_name", "resource_type", "is_lead"], "title": "NordexActivityResourceSchema", "type": "object"}, "NordexActivitySchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Free text, e.g. 'WTG off' or 'WTG off (for LER)'.", "title": "Activity Description"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Timezone-aware UTC instant. Localise it with 'turbine.location.timezone'.", "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "COMPLETED or IN_PROGRESS. Planned, cancelled and failed activities are not returned.", "title": "Status"}}, "required": ["id", "workorder_id", "activity_description", "start_datetime", "end_datetime", "status"], "title": "NordexActivitySchema", "type": "object"}, "NordexAnomalyFileSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "original_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Server-rendered cross-section diagrams are named 'cross_section_image*' and are not inspection photos.", "title": "Original Name"}}, "required": ["id", "url", "type", "original_name"], "title": "NordexAnomalyFileSchema", "type": "object"}, "NordexAnomalySchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "parent_type": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "anomaly_type": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "anomaly_sub_type": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "anomaly_major_component": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "anomaly_component": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "anomaly_sub_component": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "anomaly_material": {"anyOf": [{"$ref": "#/components/schemas/NordexIdNameSchema"}, {"type": "null"}]}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Side"}, "internal_external": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Internal External"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rib"}, "distance_to_root": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance To Root"}, "max_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Max Distance"}, "width": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Width"}, "cross_section_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Cross Section Distance"}, "cross_section_chamber_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Cross Section Chamber Distance"}, "cross_section_side": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cross Section Side"}, "cross_section_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cross Section Type"}, "stage": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Stage"}, "registered_by": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "AERONES, AI or CUSTOMER.", "title": "Registered By"}, "ai_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Null on an operator's entry. NEW means an unreviewed AI detection; take CONFIRMED only.", "title": "Ai Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "custom_values": {"items": {"$ref": "#/components/schemas/NordexCustomValueSchema"}, "title": "Custom Values", "type": "array"}, "files": {"items": {"$ref": "#/components/schemas/NordexAnomalyFileSchema"}, "title": "Files", "type": "array"}}, "required": ["id", "turbine_component_id", "parent_type", "anomaly_type", "anomaly_sub_type", "anomaly_major_component", "anomaly_component", "anomaly_sub_component", "anomaly_material", "side", "internal_external", "rib", "distance_to_root", "max_distance", "width", "cross_section_distance", "cross_section_chamber_distance", "cross_section_side", "cross_section_type", "stage", "registered_by", "ai_status", "description", "custom_values", "files"], "title": "NordexAnomalySchema", "type": "object"}, "NordexCIRDataSchema": {"additionalProperties": false, "properties": {"turbine": {"$ref": "#/components/schemas/NordexTurbineSchema"}, "turbine_components": {"description": "The turbine's blades, ordered A, B, C.", "items": {"$ref": "#/components/schemas/NordexTurbineComponentSchema"}, "title": "Turbine Components", "type": "array"}, "service_order_lines": {"description": "The IIN lines carrying this incident number, oldest first.", "items": {"$ref": "#/components/schemas/NordexServiceOrderLineSchema"}, "title": "Service Order Lines", "type": "array"}}, "required": ["turbine", "turbine_components", "service_order_lines"], "title": "NordexCIRDataSchema", "type": "object"}, "NordexComponentModelSchema": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Blade model as stored, e.g. 'NR 74.5' or 'TPI 81.5'.", "title": "Name"}, "blade_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Shear-web configuration of the model.", "title": "Blade Type"}}, "required": ["name", "blade_type"], "title": "NordexComponentModelSchema", "type": "object"}, "NordexCustomValueSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "custom_field_id": {"title": "Custom Field Id", "type": "integer"}, "custom_field_type": {"description": "TEXT, NUMBER, DATE, BOOLEAN or SELECT.", "title": "Custom Field Type", "type": "string"}, "custom_field_name": {"description": "The field's name as the customer defined it, e.g. 'Profile depth from (%)' on an anomaly or 'Nordex Incident Number' on a line.", "title": "Custom Field Name", "type": "string"}, "value": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Always a string, whatever the field's type.", "title": "Value"}}, "required": ["id", "custom_field_id", "custom_field_type", "custom_field_name", "value"], "title": "NordexCustomValueSchema", "type": "object"}, "NordexIdNameSchema": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id", "name"], "title": "NordexIdNameSchema", "type": "object"}, "NordexLocationSchema": {"additionalProperties": false, "properties": {"timezone": {"description": "IANA name of the wind park's timezone, e.g. 'America/Chicago'. Localise every activity datetime with it. The request is refused when the park has none.", "title": "Timezone", "type": "string"}}, "required": ["timezone"], "title": "NordexLocationSchema", "type": "object"}, "NordexServiceOrderLineSchema": {"additionalProperties": false, "properties": {"number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Always an IIN code, e.g. IIN-ONS; other services are refused.", "title": "Service Code"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "NOT_STARTED, IN_PROGRESS, FIELD_COMPLETED or COMPLETED. Cancelled lines are not returned.", "title": "Status"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "The blade this line covers, or null for a whole-turbine line.", "title": "Turbine Component Id"}, "custom_values": {"description": "The line's customer-defined fields, including the incident number and the purchase order id.", "items": {"$ref": "#/components/schemas/NordexCustomValueSchema"}, "title": "Custom Values", "type": "array"}, "purchase_order_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Current order number of the purchase order the line's 'Nordex Purchase Order' value points at, when that order is linked to the line's project; otherwise null.", "title": "Purchase Order Number"}, "workorders": {"items": {"$ref": "#/components/schemas/NordexWorkorderSchema"}, "title": "Workorders", "type": "array"}, "activities": {"items": {"$ref": "#/components/schemas/NordexActivitySchema"}, "title": "Activities", "type": "array"}, "activity_resources": {"items": {"$ref": "#/components/schemas/NordexActivityResourceSchema"}, "title": "Activity Resources", "type": "array"}, "anomalies": {"description": "Every anomaly recorded on the turbine's blades by this line, damage and blade-ID photos alike. AI detections are flagged, not filtered.", "items": {"$ref": "#/components/schemas/NordexAnomalySchema"}, "title": "Anomalies", "type": "array"}}, "required": ["number", "service_code", "status", "turbine_component_id", "custom_values", "purchase_order_number", "workorders", "activities", "activity_resources", "anomalies"], "title": "NordexServiceOrderLineSchema", "type": "object"}, "NordexTurbineComponentSchema": {"additionalProperties": false, "properties": {"id": {"description": "Join key for 'turbine_component_id' on service order lines and anomalies.", "title": "Id", "type": "integer"}, "position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Position"}, "manufacturer_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The OEM's serial as stamped on the blade, e.g. 'N2-742-0048-0013'; its fourth group is the blade set number. OpsHub's own 'serial_number' is the operator's label and is not sent.", "title": "Manufacturer Serial Number"}, "manufacturer": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Manufacturer"}, "manufacturer_component_model": {"anyOf": [{"$ref": "#/components/schemas/NordexComponentModelSchema"}, {"type": "null"}]}}, "required": ["id", "position", "manufacturer_serial_number", "manufacturer", "manufacturer_component_model"], "title": "NordexTurbineComponentSchema", "type": "object"}, "NordexTurbineSchema": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "manufacturer_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "The Nordex turbine ID as stored. Never derived from 'name', which is the operator's label.", "title": "Manufacturer Number"}, "location": {"$ref": "#/components/schemas/NordexLocationSchema"}}, "required": ["name", "manufacturer_number", "location"], "title": "NordexTurbineSchema", "type": "object"}, "NordexWorkorderSchema": {"additionalProperties": false, "properties": {"id": {"description": "Join key for 'activities[].workorder_id'.", "title": "Id", "type": "integer"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "ADMIN, FIELD_WORK, FIELD_OTHER, FIELD_SITE, OFFICE, DATA_UPLOAD or DATA_TRACKING. Cancelled workorders are not returned.", "title": "Type"}}, "required": ["id", "type"], "title": "NordexWorkorderSchema", "type": "object"}, "DataTrackingStatusCountsResponse": {"additionalProperties": false, "description": "Aggregated data-tracking status counters for a batch of lines.", "properties": {"generated_at": {"format": "date-time", "title": "Generated At", "type": "string"}, "service_order_lines": {"items": {"$ref": "#/components/schemas/ServiceOrderLineStatusCounts"}, "title": "Service Order Lines", "type": "array"}, "missing_ids": {"description": "Requested ids that do not exist or the caller cannot access.", "items": {"type": "integer"}, "title": "Missing Ids", "type": "array"}, "failed_ids": {"description": "Requested ids the aggregate could not be computed for.", "items": {"type": "integer"}, "title": "Failed Ids", "type": "array"}}, "required": ["generated_at", "service_order_lines", "missing_ids", "failed_ids"], "title": "DataTrackingStatusCountsResponse", "type": "object"}, "ServiceOrderLineStatusCounts": {"additionalProperties": false, "description": "Per-stage status counters for a single service order line.", "properties": {"id": {"title": "Id", "type": "integer"}, "total_files": {"description": "Distinct tracked files. Every stage's buckets sum to this value.", "title": "Total Files", "type": "integer"}, "updated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "description": "Most recent change across the line's rows; null when none.", "title": "Updated At"}, "stages": {"additionalProperties": {"additionalProperties": {"type": "integer"}, "type": "object"}, "description": "Open map of stage key -> {status: count}. Statuses are the verbatim DataTrackingStatus values; zero buckets are omitted.", "title": "Stages", "type": "object"}}, "required": ["id", "total_files", "stages"], "title": "ServiceOrderLineStatusCounts", "type": "object"}, "DataTrackingResponse": {"additionalProperties": false, "description": "Tracked file status response (flat, aggregated across stage rows).", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "file_path": {"title": "File Path", "type": "string"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}, "upload_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Status"}, "upload_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Error"}, "upload_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Started At"}, "upload_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Finished At"}, "process_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Status"}, "process_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Error"}, "process_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Started At"}, "process_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Finished At"}, "process_logfile": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Logfile"}, "archive_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Status"}, "archive_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Error"}, "archive_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Started At"}, "archive_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Finished At"}, "archive_logfile": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Logfile"}, "import_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Status"}, "import_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Error"}, "import_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Started At"}, "import_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Finished At"}}, "required": ["updated_at", "file_path"], "title": "DataTrackingResponse", "type": "object"}, "DataTrackingCreateRequest": {"additionalProperties": false, "description": "Request body for creating a tracked file.", "properties": {"file_path": {"minLength": 1, "title": "File Path", "type": "string"}, "upload_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "upload_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Error"}, "process_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "process_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Error"}, "archive_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "archive_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Error"}, "import_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "import_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Error"}}, "required": ["file_path"], "title": "DataTrackingCreateRequest", "type": "object"}, "DataTrackingStatus": {"description": "Allowed API status values for data tracking updates.", "enum": ["NOT_STARTED", "INITIALISED", "IN-PROGRESS", "COMPLETED", "FAILED", "ABANDONED"], "title": "DataTrackingStatus", "type": "string"}, "DataTrackingUpdateRequest": {"additionalProperties": false, "description": "Request body for updating a tracked file.", "properties": {"file_path": {"minLength": 1, "title": "File Path", "type": "string"}, "upload_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "upload_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Error"}, "process_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "process_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Error"}, "archive_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "archive_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Error"}, "import_status": {"anyOf": [{"$ref": "#/components/schemas/DataTrackingStatus"}, {"type": "null"}]}, "import_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Error"}}, "required": ["file_path"], "title": "DataTrackingUpdateRequest", "type": "object"}, "DataTrackingBatchResponse": {"additionalProperties": false, "description": "Tracked file status response carrying its owning service order line.\n\nIdentical to :class:`DataTrackingResponse` plus ``service_order_line_id``,\nwhich the batch listing needs because ``file_path`` is only unique per\nstage activity \u2014 two lines may legitimately track the same path.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "file_path": {"title": "File Path", "type": "string"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "workorder_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Activity Id"}, "upload_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Status"}, "upload_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Error"}, "upload_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Started At"}, "upload_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Upload Finished At"}, "process_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Status"}, "process_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Error"}, "process_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Started At"}, "process_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Finished At"}, "process_logfile": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Process Logfile"}, "archive_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Status"}, "archive_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Error"}, "archive_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Started At"}, "archive_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Finished At"}, "archive_logfile": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Archive Logfile"}, "import_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Status"}, "import_error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Error"}, "import_started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Started At"}, "import_finished_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Import Finished At"}, "service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}}, "required": ["updated_at", "file_path", "service_order_line_id"], "title": "DataTrackingBatchResponse", "type": "object"}, "ServiceQuery": {"additionalProperties": false, "description": "Service query parameters.", "properties": {"category": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Service category.", "title": "Category"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Asset type (WTG, BLADE).", "title": "Type"}}, "title": "ServiceQuery", "type": "object"}, "ServiceList": {"additionalProperties": false, "description": "Schema for services on list.", "properties": {"code": {"description": "Unique service code.", "title": "Code", "type": "string"}, "name": {"description": "Human readable service name.", "title": "Name", "type": "string"}, "category": {"$ref": "#/components/schemas/CodeWithName", "description": "Service category."}}, "required": ["code", "name", "category"], "title": "ServiceList", "type": "object"}, "Addons": {"additionalProperties": false, "description": "Schema for service addons.", "properties": {"addons": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Additional service codes that can/or are added to the service.", "title": "Addons"}}, "title": "Addons", "type": "object"}, "ServicePreJobQuestionDefinition": {"additionalProperties": false, "description": "Single definition of a pre job question that can be attached to service.", "properties": {"key": {"description": "Unique key for the question. This key is used to store the question answer, when referencing it in a project service questionnaire.", "title": "Key", "type": "string"}, "title": {"description": "Human readable title of the question.", "title": "Title", "type": "string"}, "type": {"$ref": "#/components/schemas/ServicePreJobQuestionType", "description": "Type of the value in the answer of the question."}, "required": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Is the question required to be answered.", "title": "Required"}, "choices": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "default": [], "description": "List of possible choices for the question. Only used when type is select or multiselect.", "title": "Choices"}, "tooltip": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional tooltip text to provide additional information about the question.", "title": "Tooltip"}, "unit": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Optional unit for number type questions (e.g., kg, m, etc.).", "title": "Unit"}}, "required": ["key", "title", "type"], "title": "ServicePreJobQuestionDefinition", "type": "object"}, "ServicePreJobQuestionType": {"description": "Allowed type of the pre job question.", "enum": ["text", "select", "multiselect", "boolean", "file", "number"], "title": "ServicePreJobQuestionType", "type": "string"}, "Service": {"additionalProperties": false, "description": "Schema for unified service.", "properties": {"code": {"description": "Unique service base code.", "title": "Code", "type": "string"}, "category": {"$ref": "#/components/schemas/CodeWithName", "description": "Service category."}, "name": {"description": "Human readable service name.", "title": "Name", "type": "string"}, "conditions": {"default": [], "description": "List of conditions that describe the service, including RAT availability.", "items": {"$ref": "#/components/schemas/ServiceCondition"}, "title": "Conditions", "type": "array"}, "addons": {"default": [], "description": "List of additional service codes that can/or are added to the service.", "items": {"$ref": "#/components/schemas/CodeWithName"}, "title": "Addons", "type": "array"}, "materials": {"default": [], "description": "List of materials that are compatible with the service.", "items": {"$ref": "#/components/schemas/CodeWithName"}, "title": "Materials", "type": "array"}, "full_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full line item service code.", "title": "Full Code"}}, "required": ["code", "category", "name"], "title": "Service", "type": "object"}, "BambooHREmployeeQueryParams": {"additionalProperties": false, "description": "Query parameters for the BambooHR employees list endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by display name, first/last name, or work email (case-insensitive).", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by employment status (ACTIVE, INACTIVE, TERMINATED)", "title": "Status"}}, "title": "BambooHREmployeeQueryParams", "type": "object"}, "BambooHREmployeeResponse": {"additionalProperties": false, "description": "Row in the BambooHR employees list endpoint.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Internal BambooHREmployee PK", "title": "Id", "type": "integer"}, "bamboohr_employee_id": {"description": "External BambooHR employee ID (string)", "title": "Bamboohr Employee Id", "type": "string"}, "display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Display name", "title": "Display Name"}, "work_email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Work email", "title": "Work Email"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Employment status (ACTIVE / INACTIVE / TERMINATED)", "title": "Status"}, "cost_center": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Cost center, mirrored from BambooHR's Cost Center (1) list", "title": "Cost Center"}, "linked_resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of the core.Resource currently linked to this employee, or null if unlinked. Frontends use this to disable already-linked options in the employee selector.", "title": "Linked Resource Id"}}, "required": ["updated_at", "id", "bamboohr_employee_id"], "title": "BambooHREmployeeResponse", "type": "object"}, "AssetQueryParams": {"additionalProperties": false, "description": "Query parameters for the MaintainX assets list endpoint.", "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "external_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by MaintainX asset ID", "title": "External Id"}, "external_organization_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by MaintainX organization ID", "title": "External Organization Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by linked core RobotSet ID", "title": "Robot Set Id"}}, "title": "AssetQueryParams", "type": "object"}, "AssetResponse": {"additionalProperties": false, "description": "Row in the MaintainX assets list endpoint.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Internal Asset PK", "title": "Id", "type": "integer"}, "external_id": {"description": "MaintainX asset ID", "title": "External Id", "type": "integer"}, "external_organization_id": {"description": "MaintainX organization ID", "title": "External Organization Id", "type": "integer"}, "robot_set_id": {"description": "Linked core RobotSet ID", "title": "Robot Set Id", "type": "integer"}}, "required": ["updated_at", "id", "external_id", "external_organization_id", "robot_set_id"], "title": "AssetResponse", "type": "object"}, "TalentLMSUserQueryParams": {"additionalProperties": false, "description": "Query parameters for the TalentLMS users list endpoint.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by full name, first/last name, or email (case-insensitive).", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort by field (prefix with - for descending)", "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by user status (ACTIVE, INACTIVE)", "title": "Status"}}, "title": "TalentLMSUserQueryParams", "type": "object"}, "TalentLMSUserResponse": {"additionalProperties": false, "description": "Row in the TalentLMS users list endpoint.", "properties": {"updated_at": {"description": "Last update timestamp", "format": "date-time", "title": "Updated At", "type": "string"}, "id": {"description": "Internal TalentLMSUser PK", "title": "Id", "type": "integer"}, "talentlms_user_id": {"description": "External TalentLMS user ID (string)", "title": "Talentlms User Id", "type": "string"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Full name", "title": "Full Name"}, "email": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Email", "title": "Email"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "User status (ACTIVE / INACTIVE)", "title": "Status"}, "linked_resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "ID of the core.Resource currently linked to this TalentLMS user, or null if unlinked. Frontends use this to disable already-linked options in the user selector.", "title": "Linked Resource Id"}}, "required": ["updated_at", "id", "talentlms_user_id"], "title": "TalentLMSUserResponse", "type": "object"}, "PayType": {"enum": ["IDLE", "ON_SITE", "OFF_SITE"], "title": "PayType", "type": "string"}, "PayrollActivityOut": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "resource_id": {"title": "Resource Id", "type": "integer"}, "status": {"$ref": "#/components/schemas/Status"}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "bonus_workorders_completed": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Bonus Workorders Completed"}, "approver_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approver Comment"}, "pay_type": {"anyOf": [{"$ref": "#/components/schemas/PayType"}, {"type": "null"}]}, "work_time_log_reference_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Log Reference Id"}, "modified_by_id": {"title": "Modified By Id", "type": "integer"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "resource_id", "status", "modified_by_id", "created_at", "updated_at"], "title": "PayrollActivityOut", "type": "object"}, "Status": {"enum": ["approved", "rejected"], "title": "Status", "type": "string"}, "PayrollActivityIn": {"additionalProperties": false, "properties": {"resource_id": {"title": "Resource Id", "type": "integer"}, "status": {"$ref": "#/components/schemas/Status"}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "bonus_workorders_completed": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Bonus Workorders Completed"}, "approver_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approver Comment"}, "pay_type": {"anyOf": [{"$ref": "#/components/schemas/PayType"}, {"type": "null"}]}, "work_time_log_reference_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Log Reference Id"}}, "required": ["resource_id", "status"], "title": "PayrollActivityIn", "type": "object"}, "PayrollActivityPatchIn": {"additionalProperties": false, "properties": {"status": {"anyOf": [{"$ref": "#/components/schemas/Status"}, {"type": "null"}]}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "bonus_workorders_completed": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Bonus Workorders Completed"}, "approver_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approver Comment"}, "pay_type": {"anyOf": [{"$ref": "#/components/schemas/PayType"}, {"type": "null"}]}}, "title": "PayrollActivityPatchIn", "type": "object"}, "TimesheetQueryParams": {"additionalProperties": false, "properties": {"resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource", "title": "Resource Id"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter from date", "title": "Start Date"}, "end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter until date", "title": "End Date"}, "project_id": {"description": "Filter by project IDs", "items": {"type": "integer"}, "title": "Project Id", "type": "array"}, "robot_set_id": {"description": "Filter by robot set IDs", "items": {"type": "integer"}, "title": "Robot Set Id", "type": "array"}, "work_time_category_id": {"description": "Filter by work time category IDs", "items": {"type": "integer"}, "title": "Work Time Category Id", "type": "array"}, "exclude_null_work_time_category": {"default": false, "description": "Exclude entries where work time category is not assigned", "title": "Exclude Null Work Time Category", "type": "boolean"}}, "title": "TimesheetQueryParams", "type": "object"}, "TimesheetEntryOut": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "source": {"title": "Source", "type": "string"}, "status": {"enum": ["pending", "approved", "rejected"], "title": "Status", "type": "string"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Resource Id"}, "work_time_category_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Time Category Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "robot_set_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Robot Set Id"}, "started_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Started At"}, "ended_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Ended At"}, "duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Min"}, "pay_type": {"anyOf": [{"$ref": "#/components/schemas/PayType"}, {"type": "null"}]}, "locked": {"default": false, "title": "Locked", "type": "boolean"}, "bonus_workorders_completed": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Bonus Workorders Completed"}, "approver_comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Approver Comment"}, "payroll_activity_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Payroll Activity Id"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Created At"}, "updated_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Updated At"}, "modified_by_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Modified By Id"}, "comment": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comment"}, "work_time_log_created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Work Time Log Created At"}, "payroll_activity_created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Payroll Activity Created At"}}, "required": ["id", "source", "status"], "title": "TimesheetEntryOut", "type": "object"}, "ActiveWorkloadSOLQueryParams": {"additionalProperties": false, "description": "Query parameters for active workload service order lines listing.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by service code, description, or SO number", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix with '-' for descending. Allowed: service_code, status, number", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by SOL status", "title": "Status"}, "service_codes": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated service codes to filter by", "title": "Service Codes"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SO date on or after", "title": "Date From"}, "date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter SO date on or before", "title": "Date To"}, "project_manager_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project manager user ID", "title": "Project Manager User Id"}, "include_cancelled": {"default": false, "description": "Include cancelled lines", "title": "Include Cancelled", "type": "boolean"}}, "title": "ActiveWorkloadSOLQueryParams", "type": "object"}, "ActiveWorkloadSOLResponse": {"additionalProperties": false, "description": "Response schema for a single service order line in the active workload list.", "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "so_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "So Number"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectInfo"}, {"type": "null"}]}, "customer": {"anyOf": [{"$ref": "#/components/schemas/CustomerInfo"}, {"type": "null"}]}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationInfo"}, {"type": "null"}]}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Type Name"}, "workorders_count": {"default": 0, "title": "Workorders Count", "type": "integer"}}, "required": ["id"], "title": "ActiveWorkloadSOLResponse", "type": "object"}, "CustomerInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "CustomerInfo", "type": "object"}, "LocationInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "country": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Country"}, "city": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "City"}, "state_region": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "State Region"}, "timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Timezone"}}, "required": ["id"], "title": "LocationInfo", "type": "object"}, "ActiveWorkloadSOLDetailResponse": {"additionalProperties": false, "description": "Detail response for a service order line (modal).", "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "service_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "so_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "So Number"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectInfo"}, {"type": "null"}]}, "customer": {"anyOf": [{"$ref": "#/components/schemas/CustomerInfo"}, {"type": "null"}]}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationInfo"}, {"type": "null"}]}, "service_order_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Service Order Date"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Type Name"}, "workorders": {"default": [], "items": {"$ref": "#/components/schemas/SOLWorkorderInfo"}, "title": "Workorders", "type": "array"}}, "required": ["id"], "title": "ActiveWorkloadSOLDetailResponse", "type": "object"}, "ResourceInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Full Name"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}, "is_lead": {"default": false, "title": "Is Lead", "type": "boolean"}}, "required": ["id"], "title": "ResourceInfo", "type": "object"}, "ResourceSetInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "ResourceSetInfo", "type": "object"}, "SOLWorkorderInfo": {"additionalProperties": false, "description": "Nested WO info inside an SOL detail.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "planned_start": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start"}, "planned_end": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End"}, "resource_sets": {"default": [], "items": {"$ref": "#/components/schemas/ResourceSetInfo"}, "title": "Resource Sets", "type": "array"}, "resources": {"default": [], "items": {"$ref": "#/components/schemas/ResourceInfo"}, "title": "Resources", "type": "array"}}, "required": ["id"], "title": "SOLWorkorderInfo", "type": "object"}, "ActiveWorkloadWOQueryParams": {"additionalProperties": false, "description": "Query parameters for active workload work orders listing.", "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Search by workorder name (case-insensitive)", "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Sort field, prefix with '-' for descending. Allowed: name, status, planned_start_date, planned_end_date, so_number, latest_activity", "title": "Sort"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project ID", "title": "Project Id"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by customer ID", "title": "Customer Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by location ID", "title": "Location Id"}, "country_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by country ID", "title": "Country Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by status (comma-separated for multiple)", "title": "Status"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by turbine ID", "title": "Turbine Id"}, "component_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by component type ID", "title": "Component Type Id"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by WO type (FIELD, ADMIN, OFFICE, DATA_UPLOAD)", "title": "Type"}, "resource_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by resource ID", "title": "Resource Id"}, "resource_set_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Filter by resource set name", "title": "Resource Set Name"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "description": "Comma-separated service codes to filter by (matches service_order_line.service_code)", "title": "Service Code"}, "date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned start on or after", "title": "Date From"}, "date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter planned end on or before", "title": "Date To"}, "activity_date_from": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter WOs with activities whose time report overlaps this start date", "title": "Activity Date From"}, "activity_date_to": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "description": "Filter WOs with activities whose time report overlaps this end date", "title": "Activity Date To"}, "project_manager_user_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "description": "Filter by project manager user ID", "title": "Project Manager User Id"}, "include_cancelled": {"default": false, "description": "Include cancelled work orders", "title": "Include Cancelled", "type": "boolean"}, "has_inspection": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "description": "Filter WOs with (true) or without (false) inspection data", "title": "Has Inspection"}}, "title": "ActiveWorkloadWOQueryParams", "type": "object"}, "ActiveWorkloadWOResponse": {"additionalProperties": false, "description": "Response schema for a single work order in the active workload list.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectInfo"}, {"type": "null"}]}, "so_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "So Number"}, "service_order_line": {"anyOf": [{"$ref": "#/components/schemas/ServiceOrderLineInfo"}, {"type": "null"}]}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationInfo"}, {"type": "null"}]}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/TurbineInfo"}, {"type": "null"}]}, "component": {"anyOf": [{"$ref": "#/components/schemas/ComponentInfo"}, {"type": "null"}]}, "planned_start": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start"}, "planned_end": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End"}, "resource_sets": {"default": [], "items": {"$ref": "#/components/schemas/ResourceSetInfo"}, "title": "Resource Sets", "type": "array"}, "resources": {"default": [], "items": {"$ref": "#/components/schemas/ResourceInfo"}, "title": "Resources", "type": "array"}, "activities_count": {"default": 0, "title": "Activities Count", "type": "integer"}, "estimated_duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration Min"}, "activities_duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Activities Duration Min"}, "inspection": {"anyOf": [{"$ref": "#/components/schemas/InspectionSummary"}, {"type": "null"}]}}, "required": ["id"], "title": "ActiveWorkloadWOResponse", "type": "object"}, "ComponentInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Serial Number"}}, "required": ["id"], "title": "ComponentInfo", "type": "object"}, "InspectionSummary": {"additionalProperties": false, "properties": {"sections_total": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sections Total"}, "sections_completed": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sections Completed"}, "video_files_count": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Video Files Count"}}, "title": "InspectionSummary", "type": "object"}, "ServiceOrderLineInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "service_code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Service Code"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "turbine_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Name"}, "so_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "So Number"}}, "required": ["id"], "title": "ServiceOrderLineInfo", "type": "object"}, "ActiveWorkloadWODetailResponse": {"additionalProperties": false, "description": "Detail response for a work order (modal).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Type"}, "project": {"anyOf": [{"$ref": "#/components/schemas/ProjectInfo"}, {"type": "null"}]}, "customer": {"anyOf": [{"$ref": "#/components/schemas/CustomerInfo"}, {"type": "null"}]}, "so_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "So Number"}, "service_order_line": {"anyOf": [{"$ref": "#/components/schemas/ServiceOrderLineInfo"}, {"type": "null"}]}, "location": {"anyOf": [{"$ref": "#/components/schemas/LocationInfo"}, {"type": "null"}]}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/TurbineInfo"}, {"type": "null"}]}, "component": {"anyOf": [{"$ref": "#/components/schemas/ComponentInfo"}, {"type": "null"}]}, "planned_start": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned Start"}, "planned_end": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Planned End"}, "activities": {"default": [], "items": {"$ref": "#/components/schemas/WOActivityInfo"}, "title": "Activities", "type": "array"}, "resource_sets": {"default": [], "items": {"$ref": "#/components/schemas/WOResourceSetDetail"}, "title": "Resource Sets", "type": "array"}, "inspection": {"anyOf": [{"$ref": "#/components/schemas/InspectionDetail"}, {"type": "null"}]}}, "required": ["id"], "title": "ActiveWorkloadWODetailResponse", "type": "object"}, "InspectionComponentInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "sections": {"default": [], "items": {"$ref": "#/components/schemas/InspectionSectionInfo"}, "title": "Sections", "type": "array"}}, "required": ["id", "name"], "title": "InspectionComponentInfo", "type": "object"}, "InspectionDetail": {"additionalProperties": false, "properties": {"sections_total": {"default": 0, "title": "Sections Total", "type": "integer"}, "sections_completed": {"default": 0, "title": "Sections Completed", "type": "integer"}, "video_files_count": {"default": 0, "title": "Video Files Count", "type": "integer"}, "rosbags_count": {"default": 0, "title": "Rosbags Count", "type": "integer"}, "photos_count": {"default": 0, "title": "Photos Count", "type": "integer"}, "components": {"default": [], "items": {"$ref": "#/components/schemas/InspectionComponentInfo"}, "title": "Components", "type": "array"}}, "title": "InspectionDetail", "type": "object"}, "InspectionSectionInfo": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"title": "Status", "type": "string"}, "video_files_count": {"default": 0, "title": "Video Files Count", "type": "integer"}, "rosbags_count": {"default": 0, "title": "Rosbags Count", "type": "integer"}, "photos_count": {"default": 0, "title": "Photos Count", "type": "integer"}}, "required": ["id", "name", "status"], "title": "InspectionSectionInfo", "type": "object"}, "WOActivityInfo": {"additionalProperties": false, "description": "Nested activity for WO detail.", "properties": {"id": {"title": "Id", "type": "integer"}, "activity_description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Activity Description"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "start_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Start Datetime"}, "end_datetime": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "End Datetime"}, "duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Min"}, "estimated_duration_min": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Estimated Duration Min"}, "component_type_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Type Name"}, "location_timezone": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Location Timezone"}}, "required": ["id"], "title": "WOActivityInfo", "type": "object"}, "WOResourceSetDetail": {"additionalProperties": false, "description": "Resource set with members for WO detail.", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "members": {"default": [], "items": {"$ref": "#/components/schemas/WOResourceSetMember"}, "title": "Members", "type": "array"}}, "required": ["id"], "title": "WOResourceSetDetail", "type": "object"}, "WOResourceSetMember": {"additionalProperties": false, "description": "Resource within a resource set.", "properties": {"id": {"title": "Id", "type": "integer"}, "full_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Full Name"}, "resource_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Resource Type"}, "is_lead": {"default": false, "title": "Is Lead", "type": "boolean"}}, "required": ["id"], "title": "WOResourceSetMember", "type": "object"}, "ActiveWorkloadFiltersResponse": {"additionalProperties": false, "description": "Response schema for filter options endpoint.", "properties": {"projects": {"default": [], "items": {"$ref": "#/components/schemas/ProjectInfo"}, "title": "Projects", "type": "array"}, "customers": {"default": [], "items": {"$ref": "#/components/schemas/CustomerInfo"}, "title": "Customers", "type": "array"}, "locations": {"default": [], "items": {"$ref": "#/components/schemas/LocationInfo"}, "title": "Locations", "type": "array"}, "countries": {"default": [], "items": {"$ref": "#/components/schemas/CountryFilterOption"}, "title": "Countries", "type": "array"}, "statuses": {"allOf": [{"$ref": "#/components/schemas/FilterStatusGroup"}], "default": {"sol": [], "wo": []}}, "turbines": {"default": [], "items": {"$ref": "#/components/schemas/TurbineInfo"}, "title": "Turbines", "type": "array"}, "component_types": {"default": [], "items": {"$ref": "#/components/schemas/ComponentInfo"}, "title": "Component Types", "type": "array"}, "resources": {"default": [], "items": {"$ref": "#/components/schemas/ResourceInfo"}, "title": "Resources", "type": "array"}, "resource_sets": {"default": [], "items": {"$ref": "#/components/schemas/ResourceSetFilterOption"}, "title": "Resource Sets", "type": "array"}, "wo_types": {"default": [], "items": {"$ref": "#/components/schemas/WOTypeOption"}, "title": "Wo Types", "type": "array"}, "service_codes": {"default": [], "items": {"type": "string"}, "title": "Service Codes", "type": "array"}}, "title": "ActiveWorkloadFiltersResponse", "type": "object"}, "CountryFilterOption": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "CountryFilterOption", "type": "object"}, "FilterStatusGroup": {"additionalProperties": false, "properties": {"sol": {"default": [], "items": {"type": "string"}, "title": "Sol", "type": "array"}, "wo": {"default": [], "items": {"type": "string"}, "title": "Wo", "type": "array"}}, "title": "FilterStatusGroup", "type": "object"}, "ResourceSetFilterOption": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "ResourceSetFilterOption", "type": "object"}, "WOTypeOption": {"additionalProperties": false, "properties": {"value": {"title": "Value", "type": "string"}, "label": {"title": "Label", "type": "string"}}, "required": ["value", "label"], "title": "WOTypeOption", "type": "object"}, "Filters": {"properties": {"component_name": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Filter by component name (exact match).", "title": "Component Name"}, "component_id": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "description": "Filter by turbine component id (exact match).", "title": "Component Id"}, "section_name": {"anyOf": [{"items": {"type": "string"}, "type": "array"}, {"type": "null"}], "description": "Filter sections by name (exact match).", "title": "Section Name"}, "return_sections": {"default": true, "description": "Include component sections in the response.", "title": "Return Sections", "type": "boolean"}, "return_data": {"default": true, "description": "Include all media data.", "title": "Return Data", "type": "boolean"}, "return_urls": {"default": true, "description": "Include signed URLs for media data.", "title": "Return Urls", "type": "boolean"}}, "title": "Filters", "type": "object"}, "Ordering": {"properties": {"root_photo_ordering": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "distance,name,file_name,angle"}}, "title": "Root Photo Ordering", "type": "string"}, "poi_photo_ordering": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "distance,name,file_name,angle"}}, "title": "Poi Photo Ordering", "type": "string"}, "external_photo_ordering": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "name,file_name"}}, "title": "External Photo Ordering", "type": "string"}, "ler_photo_ordering": {"examples": {"No ordering": {"description": "No specific ordering applied, default order is used.", "value": ""}, "Ordering by specific fields": {"description": "Fields can be prefixed with '-' for descending order.", "value": "name,file_name"}}, "title": "Ler Photo Ordering", "type": "string"}}, "title": "Ordering", "type": "object"}, "ComponentSchema": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/TurbineComponentResponse"}, {"type": "null"}]}, "sections": {"anyOf": [{"items": {"$ref": "#/components/schemas/SectionSchema"}, "type": "array"}, {"type": "null"}], "title": "Sections"}}, "required": ["id", "name"], "title": "ComponentSchema", "type": "object"}, "ExternalImageStatus": {"description": "Review status of a single external photo.\n\nMirrors ``LERImageStatus`` but stays a separate enum: external photos have no\nstep/run concept, so the two review flows are free to diverge.", "enum": ["NEW", "ANOMALIES_FLAGGED", "ACCEPTED"], "title": "ExternalImageStatus", "type": "string"}, "ExternalPhotoLowResSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "ExternalPhotoLowResSchema", "type": "object"}, "ExternalPhotoSchema": {"properties": {"name": {"title": "Name", "type": "string"}, "rotation": {"title": "Rotation", "type": "integer"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance"}, "side": {"anyOf": [{"$ref": "#/components/schemas/ImageSide"}, {"type": "null"}]}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Index"}, "angle": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Angle"}, "orientation": {"anyOf": [{"$ref": "#/components/schemas/ImageOrientation"}, {"type": "null"}]}, "normalized_angle": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Normalized Angle"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "is_root_photo": {"title": "Is Root Photo", "type": "boolean"}, "pixel_distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Pixel Distance"}, "status": {"$ref": "#/components/schemas/ExternalImageStatus"}, "cdn_base_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cdn Base Url"}, "tiles": {"anyOf": [{"items": {"$ref": "#/components/schemas/ExternalPhotoTileSchema"}, "type": "array"}, {"type": "null"}], "title": "Tiles"}, "thumbnail": {"anyOf": [{"$ref": "#/components/schemas/ExternalPhotoThumbnailSchema"}, {"type": "null"}]}, "lowres": {"anyOf": [{"$ref": "#/components/schemas/ExternalPhotoLowResSchema"}, {"type": "null"}]}, "distance_to_centre": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance To Centre"}}, "required": ["name", "rotation", "id", "is_root_photo", "status"], "title": "ExternalPhotoSchema", "type": "object"}, "ExternalPhotoThumbnailSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "ExternalPhotoThumbnailSchema", "type": "object"}, "ExternalPhotoTileSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "x": {"title": "X", "type": "integer"}, "y": {"title": "Y", "type": "integer"}}, "required": ["id", "x", "y"], "title": "ExternalPhotoTileSchema", "type": "object"}, "ImageOrientation": {"enum": ["PS_DOWN", "SS_DOWN", "LE_DOWN", "DW_DOWN", "UW_DOWN"], "title": "ImageOrientation", "type": "string"}, "ImageSide": {"description": "Sides from which photos can be taken.", "enum": ["L", "R", "T"], "title": "ImageSide", "type": "string"}, "InspectionItemStatus": {"enum": ["NOT_STARTED", "IN_PROGRESS", "AI_REVIEW", "DETAILED_REVIEW", "COMPLETED"], "title": "InspectionItemStatus", "type": "string"}, "InspectionSchema": {"properties": {"id": {"title": "Id", "type": "integer"}, "service_order_line_id": {"title": "Service Order Line Id", "type": "integer"}, "components": {"anyOf": [{"items": {"$ref": "#/components/schemas/ComponentSchema"}, "type": "array"}, {"type": "null"}], "title": "Components"}}, "required": ["id", "service_order_line_id"], "title": "InspectionSchema", "type": "object"}, "LERImageStatus": {"enum": ["NEW", "ANOMALIES_FLAGGED", "ACCEPTED"], "title": "LERImageStatus", "type": "string"}, "LERInspectionStatus": {"description": "Review status of a single LER inspection step run.", "enum": ["NOT_STARTED", "IN_PROGRESS", "COMPLETED", "FLAGGED"], "title": "LERInspectionStatus", "type": "string"}, "LERPhotoGroupSchema": {"properties": {"step": {"title": "Step", "type": "string"}, "runs": {"items": {"$ref": "#/components/schemas/LERPhotoRunSchema"}, "title": "Runs", "type": "array"}}, "required": ["step", "runs"], "title": "LERPhotoGroupSchema", "type": "object"}, "LERPhotoLowResSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "LERPhotoLowResSchema", "type": "object"}, "LERPhotoRunSchema": {"properties": {"id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Id"}, "run_index": {"title": "Run Index", "type": "integer"}, "status": {"$ref": "#/components/schemas/LERInspectionStatus"}, "photos": {"items": {"$ref": "#/components/schemas/LERPhotoSchema"}, "title": "Photos", "type": "array"}}, "required": ["run_index", "status", "photos"], "title": "LERPhotoRunSchema", "type": "object"}, "LERPhotoSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "sol_id": {"title": "Sol Id", "type": "integer"}, "date": {"format": "date", "title": "Date", "type": "string"}, "blade": {"title": "Blade", "type": "string"}, "step": {"title": "Step", "type": "string"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Side"}, "photo_index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Photo Index"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "status": {"$ref": "#/components/schemas/LERImageStatus"}, "include_in_report": {"default": false, "title": "Include In Report", "type": "boolean"}, "distance_to_centre": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance To Centre"}, "cdn_base_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cdn Base Url"}, "tiles": {"anyOf": [{"items": {"$ref": "#/components/schemas/LERPhotoTileSchema"}, "type": "array"}, {"type": "null"}], "title": "Tiles"}, "thumbnail": {"anyOf": [{"$ref": "#/components/schemas/LERPhotoThumbnailSchema"}, {"type": "null"}]}, "lowres": {"anyOf": [{"$ref": "#/components/schemas/LERPhotoLowResSchema"}, {"type": "null"}]}}, "required": ["id", "name", "sol_id", "date", "blade", "step", "status"], "title": "LERPhotoSchema", "type": "object"}, "LERPhotoThumbnailSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "LERPhotoThumbnailSchema", "type": "object"}, "LERPhotoTileSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "x": {"title": "X", "type": "integer"}, "y": {"title": "Y", "type": "integer"}}, "required": ["id", "x", "y"], "title": "LERPhotoTileSchema", "type": "object"}, "POIPhotoLowResSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "POIPhotoLowResSchema", "type": "object"}, "POIPhotoSchema": {"properties": {"name": {"title": "Name", "type": "string"}, "rotation": {"title": "Rotation", "type": "integer"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance"}, "side": {"anyOf": [{"$ref": "#/components/schemas/ImageSide"}, {"type": "null"}]}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Index"}, "angle": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Angle"}, "orientation": {"anyOf": [{"$ref": "#/components/schemas/ImageOrientation"}, {"type": "null"}]}, "normalized_angle": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Normalized Angle"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "cdn_base_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cdn Base Url"}, "tiles": {"anyOf": [{"items": {"$ref": "#/components/schemas/POIPhotoTileSchema"}, "type": "array"}, {"type": "null"}], "title": "Tiles"}, "thumbnail": {"anyOf": [{"$ref": "#/components/schemas/POIPhotoThumbnailSchema"}, {"type": "null"}]}, "lowres": {"anyOf": [{"$ref": "#/components/schemas/POIPhotoLowResSchema"}, {"type": "null"}]}}, "required": ["name", "rotation", "id"], "title": "POIPhotoSchema", "type": "object"}, "POIPhotoThumbnailSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "POIPhotoThumbnailSchema", "type": "object"}, "POIPhotoTileSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "x": {"title": "X", "type": "integer"}, "y": {"title": "Y", "type": "integer"}}, "required": ["id", "x", "y"], "title": "POIPhotoTileSchema", "type": "object"}, "RootPhotoLowResSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "RootPhotoLowResSchema", "type": "object"}, "RootPhotoSchema": {"properties": {"name": {"title": "Name", "type": "string"}, "rotation": {"title": "Rotation", "type": "integer"}, "sort_order": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sort Order"}, "distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance"}, "side": {"anyOf": [{"$ref": "#/components/schemas/ImageSide"}, {"type": "null"}]}, "index": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Index"}, "angle": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Angle"}, "orientation": {"anyOf": [{"$ref": "#/components/schemas/ImageOrientation"}, {"type": "null"}]}, "normalized_angle": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Normalized Angle"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "cdn_base_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cdn Base Url"}, "tiles": {"anyOf": [{"items": {"$ref": "#/components/schemas/RootPhotoTileSchema"}, "type": "array"}, {"type": "null"}], "title": "Tiles"}, "thumbnail": {"anyOf": [{"$ref": "#/components/schemas/RootPhotoThumbnailSchema"}, {"type": "null"}]}, "lowres": {"anyOf": [{"$ref": "#/components/schemas/RootPhotoLowResSchema"}, {"type": "null"}]}}, "required": ["name", "rotation", "id"], "title": "RootPhotoSchema", "type": "object"}, "RootPhotoThumbnailSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "RootPhotoThumbnailSchema", "type": "object"}, "RootPhotoTileSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "x": {"title": "X", "type": "integer"}, "y": {"title": "Y", "type": "integer"}}, "required": ["id", "x", "y"], "title": "RootPhotoTileSchema", "type": "object"}, "SectionSchema": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "run_index": {"title": "Run Index", "type": "integer"}, "status": {"$ref": "#/components/schemas/InspectionItemStatus"}, "video_files": {"anyOf": [{"items": {"$ref": "#/components/schemas/VideoFileSchema"}, "type": "array"}, {"type": "null"}], "title": "Video Files"}, "root_photos": {"anyOf": [{"items": {"$ref": "#/components/schemas/RootPhotoSchema"}, "type": "array"}, {"type": "null"}], "title": "Root Photos"}, "poi_photos": {"anyOf": [{"items": {"$ref": "#/components/schemas/POIPhotoSchema"}, "type": "array"}, {"type": "null"}], "title": "Poi Photos"}, "external_photos": {"anyOf": [{"items": {"$ref": "#/components/schemas/ExternalPhotoSchema"}, "type": "array"}, {"type": "null"}], "title": "External Photos"}, "ler_photos": {"anyOf": [{"items": {"$ref": "#/components/schemas/LERPhotoGroupSchema"}, "type": "array"}, {"type": "null"}], "title": "Ler Photos"}}, "required": ["id", "name", "run_index", "status"], "title": "SectionSchema", "type": "object"}, "VideoFileBlobKind": {"const": "QR_DETECTION", "enum": ["QR_DETECTION"], "title": "VideoFileBlobKind", "type": "string"}, "VideoFileBlobSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "kind": {"$ref": "#/components/schemas/VideoFileBlobKind"}}, "required": ["id", "kind"], "title": "VideoFileBlobSchema", "type": "object"}, "VideoFileExtension": {"description": "Expected video file formats from inspection data uploads.", "enum": ["360", "insv"], "title": "VideoFileExtension", "type": "string"}, "VideoFileSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "extension": {"$ref": "#/components/schemas/VideoFileExtension"}, "status": {"$ref": "#/components/schemas/InspectionItemStatus"}, "recording_start_time": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Recording Start Time"}, "qr_position": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Qr Position"}, "qr_detections": {"anyOf": [{"items": {"$ref": "#/components/schemas/VideoFileBlobSchema"}, "type": "array"}, {"type": "null"}], "title": "Qr Detections"}, "hls_playlist_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Hls Playlist Url"}, "vtt_file_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Vtt File Url"}, "model_url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Model Url"}, "model_3d_exists": {"default": false, "title": "Model 3D Exists", "type": "boolean"}, "snapshots": {"items": {"$ref": "#/components/schemas/VideoSnapshotSchema"}, "title": "Snapshots", "type": "array"}}, "required": ["id", "name", "extension", "status"], "title": "VideoFileSchema", "type": "object"}, "VideoSnapshotSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "timestamp": {"title": "Timestamp", "type": "number"}, "distance": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance"}, "distance_to_hub_centre": {"anyOf": [{"type": "number"}, {"type": "null"}], "description": "distance + the turbine model's center_to_root_offset (OH-4169), additive on top of the unchanged root-based `distance`. None when the turbine's model has no offset configured \u2014 never falls back to a root-based number under this key.", "title": "Distance To Hub Centre"}}, "required": ["timestamp"], "title": "VideoSnapshotSchema", "type": "object"}, "PostComponentLinkSchema": {"properties": {"component_id": {"title": "Component Id", "type": "integer"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}}, "required": ["component_id", "turbine_component_id"], "title": "PostComponentLinkSchema", "type": "object"}, "RosbagBlobDistancesSchema": {"properties": {"distances": {"additionalProperties": {"type": "number"}, "title": "Distances", "type": "object"}}, "required": ["distances"], "title": "RosbagBlobDistancesSchema", "type": "object"}, "RosbagBlobRangesSchema": {"properties": {"distance": {"title": "Distance", "type": "number"}, "ranges": {"items": {"anyOf": [{"type": "number"}, {"type": "string"}]}, "title": "Ranges", "type": "array"}}, "required": ["distance", "ranges"], "title": "RosbagBlobRangesSchema", "type": "object"}, "RosbagSchema": {"properties": {"id": {"title": "Id", "type": "integer"}}, "required": ["id"], "title": "RosbagSchema", "type": "object"}, "RosbagBlobKind": {"enum": ["QR_RANGES", "POINTCLOUD_MD"], "title": "RosbagBlobKind", "type": "string"}, "RosbagBlobSchema": {"properties": {"url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "id": {"title": "Id", "type": "integer"}, "kind": {"$ref": "#/components/schemas/RosbagBlobKind"}}, "required": ["id", "kind"], "title": "RosbagBlobSchema", "type": "object"}, "AiAnomalyCoreSchema": {"description": "The ``core.anomaly`` columns registration writes that vis.ai_anomaly lacks.\n\nA registration spans two tables, and until this existed the response showed\nonly the vis half \u2014 so a caller could not tell a column it never sent from\none the service dropped, and had to query the database to find out. Covers\nthe taxonomy cascade, the blade context resolved from\n``service_order_line_id`` + ``component_name``, and the fields that are\nderived when omitted (``name``, ``rib``).", "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "rib": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Rib"}, "side": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Side"}, "cross_section_side": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cross Section Side"}, "cross_section_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Cross Section Type"}, "comments": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comments"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "source_object_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Object Id"}, "source_object_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Object Type Id"}, "registration_origin": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Registration Origin"}, "qr_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Qr Code"}, "segmentation": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Segmentation"}, "segmentation_version": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Segmentation Version"}, "ai_images_v2": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Ai Images V2"}, "anomaly_major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Major Component Id"}, "anomaly_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Component Id"}, "anomaly_sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Sub Component Id"}, "anomaly_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Type Id"}, "anomaly_sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Sub Type Id"}, "anomaly_material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Material Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "turbine_component_serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Turbine Component Serial Number"}}, "required": ["id"], "title": "AiAnomalyCoreSchema", "type": "object"}, "AiAnomalySchema": {"description": "Response for a vis.AiAnomaly row \u2014 every column on the table.\n\n``deleted_at`` is deliberately omitted (soft-delete internals are never\nexposed); ``core_anomaly_id`` is the ``anomaly`` FK under its API name, and\n``core_anomaly`` carries the half of the registration that lives on\n``core.anomaly``.", "properties": {"id": {"title": "Id", "type": "integer"}, "inference_defect_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Inference Defect Id"}, "defect_uid": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Defect Uid"}, "internal_external": {"title": "Internal External", "type": "string"}, "core_anomaly_id": {"title": "Core Anomaly Id", "type": "integer"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}, "frame_blob_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Frame Blob Path"}, "original_image_dest": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Original Image Dest"}, "inference_job_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Inference Job Id"}, "frame_nr": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Frame Nr"}, "severity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Severity"}, "defect_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Defect Type"}, "type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Type Id"}, "sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sub Type Id"}, "material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Material Id"}, "conf_score": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Conf Score"}, "distance_from_root": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance From Root"}, "size_h_mm": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Size H Mm"}, "size_v_mm": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Size V Mm"}, "bbox": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Bbox"}, "filename": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Filename"}, "extension": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Extension"}, "ai_model_config_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Ai Model Config Id"}, "ai_model_release": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ai Model Release"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}, "core_anomaly": {"$ref": "#/components/schemas/AiAnomalyCoreSchema"}}, "required": ["id", "internal_external", "core_anomaly_id", "created_at", "updated_at", "core_anomaly"], "title": "AiAnomalySchema", "type": "object"}, "AiAnomalyRegisterSchema": {"description": "Input for POST /vis/v1/ai-anomalies \u2014 the REST twin of registerAiDefect.\n\nField names and semantics mirror the GraphQL ``RegisterAiDefectInput``; both\nsurfaces feed the same ``vis.anomalies.register_ai_defect`` service.\n\nExactly one identifier must be supplied, matching internal_external:\n``inference_defect_id`` for INTERNAL detections (they exist in the inference\npipeline) or ``defect_uid`` for EXTERNAL ones (they do not). BOTH accepts\neither. This mirrors the vis.AiAnomaly CHECK constraints.\n\n``component_name`` is the VIS blade name used to resolve the blade context.\nThe six ``*_component_id`` / ``*_type_id`` / ``material_id`` fields are the\nanomaly taxonomy cascade and land on ``core.anomaly``. External detections\nsend none of them in practice, nor a ``qr_code`` or ``segmentation``. None\nof that is enforced \u2014 the importer imposes no such restriction either, and\n``type_id`` / ``sub_type_id`` / ``material_id`` have always been accepted\nfor externals.\n\n``name`` and ``rib`` are optional because a caller need not know them:\nomitted, they are derived from the blade context \u2014 ``component_name``, or\nthe blade section of the ``source_object`` \u2014 matching what\n``AIAnomalyImporter`` writes for a pulled defect. A supplied value wins.", "properties": {"inference_defect_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Inference Defect Id"}, "defect_uid": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Defect Uid"}, "internal_external": {"default": "INTERNAL", "enum": ["INTERNAL", "EXTERNAL", "BOTH"], "title": "Internal External", "type": "string"}, "service_order_line_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Line Id"}, "component_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Component Name"}, "inference_job_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Inference Job Id"}, "frame_nr": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Frame Nr"}, "severity": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Severity"}, "defect_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Defect Type"}, "major_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Major Component Id"}, "component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Component Id"}, "sub_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sub Component Id"}, "type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Type Id"}, "sub_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Sub Type Id"}, "material_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Material Id"}, "conf_score": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Conf Score"}, "distance_from_root": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Distance From Root"}, "size_h_mm": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Size H Mm"}, "size_v_mm": {"anyOf": [{"type": "number"}, {"type": "null"}], "title": "Size V Mm"}, "bbox": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Bbox"}, "qr_code": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Qr Code"}, "segmentation": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Segmentation"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "rib": {"anyOf": [{"enum": ["TRAILING_EDGE", "LEADING_EDGE", "MID_1", "MID_2", "MID_3"], "type": "string"}, {"type": "null"}], "title": "Rib"}, "side": {"anyOf": [{"enum": ["PRESSURE_SIDE", "SUCTION_SIDE", "TRAILING_EDGE", "LEADING_EDGE"], "type": "string"}, {"type": "null"}], "title": "Side"}, "cross_section_side": {"anyOf": [{"enum": ["SUCTION_SIDE", "PRESSURE_SIDE", "MSW1", "MSW2", "TE_WEB", "END_WEB", "BEAM_LE", "BEAM_TE", "BEAM_PS", "BEAM_SS"], "type": "string"}, {"type": "null"}], "title": "Cross Section Side"}, "comments": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Comments"}, "workorder_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Workorder Id"}, "source_object_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Object Id"}, "source_object_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Object Type Id"}, "registration_origin": {"anyOf": [{"enum": ["INSPECTION_PLATFORM", "VIS", "ANOMALY_APP", "OPS_HUB"], "type": "string"}, {"type": "null"}], "title": "Registration Origin"}, "replace": {"default": false, "title": "Replace", "type": "boolean"}, "original_image_dest": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Original Image Dest"}, "frame_blob_path": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Frame Blob Path"}, "filename": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Filename"}, "extension": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Extension"}, "ai_model_config_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Ai Model Config Id"}, "ai_model_release": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ai Model Release"}}, "title": "AiAnomalyRegisterSchema", "type": "object"}, "AiAnomalySourceObjectSchema": {"description": "Input for PATCH /vis/v1/ai-anomalies/{id}/source-object.\n\nThe drone pipeline registers a defect before the portal has registered the\nphoto it came from, so the generic ``source_object`` pair is filled in once\nthat id exists.\n\nA partial update: an omitted field is left untouched, while an explicit\n``null`` clears that column. Patching one half of the pair never disturbs\nthe other, so the handler forwards presence rather than value.", "properties": {"source_object_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Object Id"}, "source_object_type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Source Object Type Id"}}, "title": "AiAnomalySourceObjectSchema", "type": "object"}, "CampaignWithScopeResponse": {"properties": {"campaign": {"$ref": "#/components/schemas/NestedCampaign"}, "work_packages": {"items": {"$ref": "#/components/schemas/NestedWorkPackage"}, "title": "Work Packages", "type": "array"}}, "required": ["campaign", "work_packages"], "title": "CampaignWithScopeResponse", "type": "object"}, "NestedCampaign": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "NestedCampaign", "type": "object"}, "NestedWorkPackage": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "campaign": {"anyOf": [{"$ref": "#/components/schemas/NestedCampaign"}, {"type": "null"}]}}, "required": ["id", "name"], "title": "NestedWorkPackage", "type": "object"}, "CampaignWithScopeCreate": {"additionalProperties": false, "description": "Create a Campaign pre-scoped to a set of parks in one atomic call.\n\nReplaces AeroCore's best-effort multi-call orchestration (create Campaign,\nthen N WorkPackages, then cleanup-on-failure). One WorkPackage is created per\n``location_ids`` entry, each pinned via ``WorkPackage.site``.", "properties": {"name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "location_ids": {"items": {"type": "integer"}, "title": "Location Ids", "type": "array"}, "work_package_status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Work Package Status"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}}, "required": ["name", "location_ids"], "title": "CampaignWithScopeCreate", "type": "object"}, "CampaignQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}}, "title": "CampaignQueryParams", "type": "object"}, "AttachmentResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "storage_id": {"title": "Storage Id", "type": "string"}, "file_name": {"default": "", "title": "File Name", "type": "string"}, "file_type": {"default": "", "title": "File Type", "type": "string"}}, "required": ["id", "storage_id"], "title": "AttachmentResponse", "type": "object"}, "CampaignResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"title": "Status", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "comments": {"default": [], "items": {"$ref": "#/components/schemas/CommentResponse"}, "title": "Comments", "type": "array"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/AttachmentResponse"}, "title": "Attachments", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "status", "created_at", "updated_at"], "title": "CampaignResponse", "type": "object"}, "CommentResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "body": {"title": "Body", "type": "string"}, "created_at": {"anyOf": [{"format": "date-time", "type": "string"}, {"type": "null"}], "title": "Created At"}, "created_by_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Created By Id"}}, "required": ["id", "body"], "title": "CommentResponse", "type": "object"}, "CampaignCreate": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["name"], "title": "CampaignCreate", "type": "object"}, "CampaignUpdate": {"properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "title": "CampaignUpdate", "type": "object"}, "CommentCreate": {"additionalProperties": false, "properties": {"body": {"title": "Body", "type": "string"}}, "required": ["body"], "title": "CommentCreate", "type": "object"}, "AttachmentCreate": {"additionalProperties": false, "properties": {"storage_id": {"title": "Storage Id", "type": "string"}, "file_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "", "title": "File Name"}, "file_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "", "title": "File Type"}}, "required": ["storage_id"], "title": "AttachmentCreate", "type": "object"}, "WorkPackageScopeRow": {"properties": {"work_package_id": {"title": "Work Package Id", "type": "integer"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}}, "required": ["work_package_id"], "title": "WorkPackageScopeRow", "type": "object"}, "WorkPackageWithScopeResponse": {"properties": {"work_packages": {"items": {"$ref": "#/components/schemas/WorkPackageScopeRow"}, "title": "Work Packages", "type": "array"}}, "required": ["work_packages"], "title": "WorkPackageWithScopeResponse", "type": "object"}, "WorkPackageWithScopeCreate": {"additionalProperties": false, "description": "Create work package(s) pre-scoped to selected turbines (or a park) atomically.\n\nProductionises AeroCore's ``create-work-package-with-scope`` Track-2 shim (a\nper-turbine loop with client-side cleanup-on-failure) as one transaction.\n\n``mode``:\n- ``\"single\"`` / ``\"per-turbine\"`` \u2014 one WorkPackage per ``turbine_ids`` entry,\n each pinned via ``WorkPackage.turbine``.\n- ``\"one-for-all\"`` \u2014 a single WorkPackage covering a whole park, pinned via\n ``WorkPackage.site`` (turbines are not individually linked).", "properties": {"mode": {"title": "Mode", "type": "string"}, "campaign_id": {"title": "Campaign Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Status"}, "turbine_ids": {"default": [], "items": {"type": "integer"}, "title": "Turbine Ids", "type": "array"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["mode", "campaign_id", "name"], "title": "WorkPackageWithScopeCreate", "type": "object"}, "WorkPackageCampaignRow": {"description": "A work package on a turbine, projected with its parent campaign.\n\nFeeds the Turbines-overview \"active campaigns affecting\" widget / side panel.\nProductionises AeroCore's ``get-turbines-with-active-campaigns`` shim.", "properties": {"turbine_id": {"title": "Turbine Id", "type": "integer"}, "campaign_id": {"title": "Campaign Id", "type": "integer"}, "campaign_name": {"title": "Campaign Name", "type": "string"}, "campaign_status": {"title": "Campaign Status", "type": "string"}}, "required": ["turbine_id", "campaign_id", "campaign_name", "campaign_status"], "title": "WorkPackageCampaignRow", "type": "object"}, "WorkPackagesWithCampaignsResponse": {"properties": {"work_packages": {"items": {"$ref": "#/components/schemas/WorkPackageCampaignRow"}, "title": "Work Packages", "type": "array"}}, "required": ["work_packages"], "title": "WorkPackagesWithCampaignsResponse", "type": "object"}, "WorkPackageQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "active_only": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Active Only"}}, "title": "WorkPackageQueryParams", "type": "object"}, "NestedSite": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "NestedSite", "type": "object"}, "NestedTurbine": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "required": ["id"], "title": "NestedTurbine", "type": "object"}, "NestedTurbineComponent": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "serial_number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Serial Number"}}, "required": ["id"], "title": "NestedTurbineComponent", "type": "object"}, "NestedVendor": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "NestedVendor", "type": "object"}, "WorkPackageResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"title": "Status", "type": "string"}, "campaign_id": {"title": "Campaign Id", "type": "integer"}, "campaign": {"anyOf": [{"$ref": "#/components/schemas/NestedCampaign"}, {"type": "null"}]}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/NestedVendor"}, {"type": "null"}]}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "site": {"anyOf": [{"$ref": "#/components/schemas/NestedSite"}, {"type": "null"}]}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/NestedTurbine"}, {"type": "null"}]}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/NestedTurbineComponent"}, {"type": "null"}]}, "comments": {"default": [], "items": {"$ref": "#/components/schemas/CommentResponse"}, "title": "Comments", "type": "array"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/AttachmentResponse"}, "title": "Attachments", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "status", "campaign_id", "created_at", "updated_at"], "title": "WorkPackageResponse", "type": "object"}, "WorkPackageCreate": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Status"}, "campaign_id": {"title": "Campaign Id", "type": "integer"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}}, "required": ["name", "campaign_id"], "title": "WorkPackageCreate", "type": "object"}, "WorkPackageUpdate": {"properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}}, "title": "WorkPackageUpdate", "type": "object"}, "ClientWorkOrderQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "task_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Task Type"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "work_package_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Package Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "unassigned": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Unassigned"}}, "title": "ClientWorkOrderQueryParams", "type": "object"}, "ClientWorkOrderResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "task_type": {"title": "Task Type", "type": "string"}, "status": {"title": "Status", "type": "string"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "site": {"anyOf": [{"$ref": "#/components/schemas/NestedSite"}, {"type": "null"}]}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine": {"anyOf": [{"$ref": "#/components/schemas/NestedTurbine"}, {"type": "null"}]}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "turbine_component": {"anyOf": [{"$ref": "#/components/schemas/NestedTurbineComponent"}, {"type": "null"}]}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "campaign": {"anyOf": [{"$ref": "#/components/schemas/NestedCampaign"}, {"type": "null"}]}, "work_package_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Package Id"}, "work_package": {"anyOf": [{"$ref": "#/components/schemas/NestedWorkPackage"}, {"type": "null"}]}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/NestedVendor"}, {"type": "null"}]}, "activities": {"default": [], "items": {"$ref": "#/components/schemas/CwmActivityResponse"}, "title": "Activities", "type": "array"}, "comments": {"default": [], "items": {"$ref": "#/components/schemas/CommentResponse"}, "title": "Comments", "type": "array"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/AttachmentResponse"}, "title": "Attachments", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "task_type", "status", "created_at", "updated_at"], "title": "ClientWorkOrderResponse", "type": "object"}, "CwmActivityResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "client_work_order_id": {"title": "Client Work Order Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "completed": {"default": false, "title": "Completed", "type": "boolean"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "position": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Position"}, "custom_fields": {"default": [], "items": {}, "title": "Custom Fields", "type": "array"}, "comments": {"default": [], "items": {"$ref": "#/components/schemas/CommentResponse"}, "title": "Comments", "type": "array"}, "attachments": {"default": [], "items": {"$ref": "#/components/schemas/AttachmentResponse"}, "title": "Attachments", "type": "array"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "client_work_order_id", "updated_at"], "title": "CwmActivityResponse", "type": "object"}, "ClientWorkOrderCreate": {"additionalProperties": false, "properties": {"task_type": {"title": "Task Type", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Status"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "work_package_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Package Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "template_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Template Id"}}, "required": ["task_type"], "title": "ClientWorkOrderCreate", "type": "object"}, "ClientWorkOrderUpdate": {"properties": {"task_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Task Type"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Start Date"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "work_package_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Package Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}}, "title": "ClientWorkOrderUpdate", "type": "object"}, "CompleteWorkOrderResult": {"description": "Per-work-order outcome of the atomic complete + cascade (AECP-333).", "properties": {"id": {"title": "Id", "type": "integer"}, "status_updated": {"title": "Status Updated", "type": "boolean"}, "cascade": {"title": "Cascade", "type": "string"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "error": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Error"}}, "required": ["id", "status_updated", "cascade"], "title": "CompleteWorkOrderResult", "type": "object"}, "CompleteWorkOrdersResponse": {"additionalProperties": false, "properties": {"results": {"items": {"$ref": "#/components/schemas/CompleteWorkOrderResult"}, "title": "Results", "type": "array"}}, "required": ["results"], "title": "CompleteWorkOrdersResponse", "type": "object"}, "CompleteWorkOrdersPayload": {"additionalProperties": false, "description": "Mark one or more work orders complete (+ cascade linked anomalies).", "properties": {"work_order_ids": {"items": {"type": "integer"}, "title": "Work Order Ids", "type": "array"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}}, "required": ["work_order_ids"], "title": "CompleteWorkOrdersPayload", "type": "object"}, "CwmApplyTemplatePayload": {"additionalProperties": false, "properties": {"template_id": {"title": "Template Id", "type": "integer"}}, "required": ["template_id"], "title": "CwmApplyTemplatePayload", "type": "object"}, "CwmActivityQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "client_work_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Client Work Order Id"}}, "title": "CwmActivityQueryParams", "type": "object"}, "CwmActivityCreate": {"additionalProperties": false, "properties": {"client_work_order_id": {"title": "Client Work Order Id", "type": "integer"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "completed": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "default": false, "title": "Completed"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Custom Fields"}}, "required": ["client_work_order_id"], "title": "CwmActivityCreate", "type": "object"}, "CwmActivityUpdate": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "completed": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Completed"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "due_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Due Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Custom Fields"}}, "title": "CwmActivityUpdate", "type": "object"}, "CwmActivityReorderPayload": {"additionalProperties": false, "properties": {"client_work_order_id": {"title": "Client Work Order Id", "type": "integer"}, "ordered_ids": {"items": {"type": "integer"}, "title": "Ordered Ids", "type": "array"}}, "required": ["client_work_order_id", "ordered_ids"], "title": "CwmActivityReorderPayload", "type": "object"}, "CwmActivityTemplateQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}}, "title": "CwmActivityTemplateQueryParams", "type": "object"}, "CwmActivityTemplateResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "steps": {"default": [], "items": {}, "title": "Steps", "type": "array"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "updated_at"], "title": "CwmActivityTemplateResponse", "type": "object"}, "CwmActivityTemplateCreate": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}, "steps": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Steps"}}, "required": ["name"], "title": "CwmActivityTemplateCreate", "type": "object"}, "CwmActivityTemplateUpdate": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "steps": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Steps"}}, "title": "CwmActivityTemplateUpdate", "type": "object"}, "CwmVendorQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "title": "CwmVendorQueryParams", "type": "object"}, "CwmVendorResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "updated_at"], "title": "CwmVendorResponse", "type": "object"}, "CwmVendorCreate": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "CwmVendorCreate", "type": "object"}, "CwmVendorUpdate": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "title": "CwmVendorUpdate", "type": "object"}, "CwmTaskTypeQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "title": "CwmTaskTypeQueryParams", "type": "object"}, "CwmTaskTypeResponse": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "updated_at"], "title": "CwmTaskTypeResponse", "type": "object"}, "CwmTaskTypeCreate": {"additionalProperties": false, "properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "CwmTaskTypeCreate", "type": "object"}, "CwmTaskTypeUpdate": {"additionalProperties": false, "properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}}, "title": "CwmTaskTypeUpdate", "type": "object"}, "StatusOption": {"additionalProperties": false, "properties": {"value": {"title": "Value", "type": "string"}, "label": {"title": "Label", "type": "string"}, "color": {"title": "Color", "type": "string"}}, "required": ["value", "label", "color"], "title": "StatusOption", "type": "object"}, "StatusesResponse": {"additionalProperties": false, "properties": {"work_order": {"items": {"$ref": "#/components/schemas/StatusOption"}, "title": "Work Order", "type": "array"}, "campaign": {"items": {"$ref": "#/components/schemas/StatusOption"}, "title": "Campaign", "type": "array"}, "work_package": {"items": {"$ref": "#/components/schemas/StatusOption"}, "title": "Work Package", "type": "array"}}, "required": ["work_order", "campaign", "work_package"], "title": "StatusesResponse", "type": "object"}, "AnomalyWorkOrderSummary": {"additionalProperties": false, "properties": {"id": {"title": "Id", "type": "integer"}, "task_type": {"title": "Task Type", "type": "string"}, "status": {"title": "Status", "type": "string"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "anomalyIds": {"default": [], "items": {"type": "integer"}, "title": "Anomalyids", "type": "array"}}, "required": ["id", "task_type", "status"], "title": "AnomalyWorkOrderSummary", "type": "object"}, "AnomalyWorkOrdersResponse": {"additionalProperties": false, "properties": {"work_orders": {"items": {"$ref": "#/components/schemas/AnomalyWorkOrderSummary"}, "title": "Work Orders", "type": "array"}}, "required": ["work_orders"], "title": "AnomalyWorkOrdersResponse", "type": "object"}, "AnomalyWorkOrdersCreatePayload": {"additionalProperties": false, "properties": {"anomalies": {"items": {"type": "integer"}, "title": "Anomalies", "type": "array"}, "task_type": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Task Type"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "work_package_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Package Id"}, "site_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Site Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "draft", "title": "Status"}, "work_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Work Order Id"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["anomalies"], "title": "AnomalyWorkOrdersCreatePayload", "type": "object"}, "PlanningCampaignQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}}, "title": "PlanningCampaignQueryParams", "type": "object"}, "PlanningCampaignResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"title": "Status", "type": "string"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "currency": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCurrency"}, {"type": "null"}]}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "status", "customer_id", "created_at", "updated_at"], "title": "PlanningCampaignResponse", "type": "object"}, "PlanningNestedCurrency": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "code", "name"], "title": "PlanningNestedCurrency", "type": "object"}, "PlanningNestedCustomer": {"properties": {"id": {"title": "Id", "type": "integer"}, "display_name": {"title": "Display Name", "type": "string"}}, "required": ["id", "display_name"], "title": "PlanningNestedCustomer", "type": "object"}, "PlanningCampaignCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "PLANNED", "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["customer_id", "name"], "title": "PlanningCampaignCreate", "type": "object"}, "PlanningCampaignUpdate": {"properties": {"name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "title": "PlanningCampaignUpdate", "type": "object"}, "PlanningProjectQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}}, "title": "PlanningProjectQueryParams", "type": "object"}, "PlanningNestedCampaign": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "PlanningNestedCampaign", "type": "object"}, "PlanningNestedCoreProject": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}}, "required": ["id", "code"], "title": "PlanningNestedCoreProject", "type": "object"}, "PlanningProjectResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "status": {"title": "Status", "type": "string"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "campaign": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCampaign"}, {"type": "null"}]}, "core_project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Project Id"}, "core_project": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCoreProject"}, {"type": "null"}]}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "currency": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCurrency"}, {"type": "null"}]}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "status", "customer_id", "created_at", "updated_at"], "title": "PlanningProjectResponse", "type": "object"}, "PlanningProjectCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "core_project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Project Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "PLANNED", "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "required": ["customer_id", "name"], "title": "PlanningProjectCreate", "type": "object"}, "PlanningProjectUpdate": {"properties": {"campaign_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Campaign Id"}, "core_project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Project Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "currency_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Currency Id"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}}, "title": "PlanningProjectUpdate", "type": "object"}, "PlanningServiceQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "core_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Service Id"}, "active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Active"}}, "title": "PlanningServiceQueryParams", "type": "object"}, "PlanningNestedCoreService": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["id", "code"], "title": "PlanningNestedCoreService", "type": "object"}, "PlanningServiceResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "active": {"title": "Active", "type": "boolean"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "core_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Service Id"}, "core_service": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCoreService"}, {"type": "null"}]}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "code", "active", "customer_id", "created_at", "updated_at"], "title": "PlanningServiceResponse", "type": "object"}, "PlanningServiceCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "core_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Service Id"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "active": {"default": true, "title": "Active", "type": "boolean"}}, "required": ["customer_id", "code"], "title": "PlanningServiceCreate", "type": "object"}, "PlanningServiceUpdate": {"properties": {"core_service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Core Service Id"}, "code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Active"}}, "title": "PlanningServiceUpdate", "type": "object"}, "PlanningCustomerVendorQueryParams": {"additionalProperties": false, "properties": {"sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}}, "title": "PlanningCustomerVendorQueryParams", "type": "object"}, "PlanningCustomerVendorResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "vendor_id": {"title": "Vendor Id", "type": "integer"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedVendor"}, {"type": "null"}]}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "customer_id", "vendor_id", "created_at", "updated_at"], "title": "PlanningCustomerVendorResponse", "type": "object"}, "PlanningNestedVendor": {"properties": {"id": {"title": "Id", "type": "integer"}, "display_name": {"title": "Display Name", "type": "string"}}, "required": ["id", "display_name"], "title": "PlanningNestedVendor", "type": "object"}, "PlanningCustomerVendorCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "vendor_id": {"title": "Vendor Id", "type": "integer"}}, "required": ["customer_id", "vendor_id"], "title": "PlanningCustomerVendorCreate", "type": "object"}, "PlanningCustomerVendorUpdate": {"properties": {"vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}}, "title": "PlanningCustomerVendorUpdate", "type": "object"}, "PlanningNestedCustomerVendor": {"properties": {"id": {"title": "Id", "type": "integer"}, "vendor_id": {"title": "Vendor Id", "type": "integer"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedVendor"}, {"type": "null"}]}}, "required": ["id", "vendor_id"], "title": "PlanningNestedCustomerVendor", "type": "object"}, "PlanningNestedProject": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}}, "required": ["id", "name"], "title": "PlanningNestedProject", "type": "object"}, "PlanningNestedService": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["id", "code"], "title": "PlanningNestedService", "type": "object"}, "PlanningServiceOrderResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "status": {"title": "Status", "type": "string"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "project": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedProject"}, {"type": "null"}]}, "service_id": {"title": "Service Id", "type": "integer"}, "service": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedService"}, {"type": "null"}]}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "vendor": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomerVendor"}, {"type": "null"}]}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "anomaly_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Anomaly Id"}, "anomaly_ids": {"default": [], "items": {"type": "integer"}, "title": "Anomaly Ids", "type": "array"}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "status", "customer_id", "service_id", "created_at", "updated_at"], "title": "PlanningServiceOrderResponse", "type": "object"}, "PlanningServiceOrderAnomalyLinkRequest": {"additionalProperties": false, "properties": {"anomaly_ids": {"items": {"type": "integer"}, "title": "Anomaly Ids", "type": "array"}}, "required": ["anomaly_ids"], "title": "PlanningServiceOrderAnomalyLinkRequest", "type": "object"}, "PlanningServiceOrderQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}}, "title": "PlanningServiceOrderQueryParams", "type": "object"}, "PlanningServiceOrderCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "service_id": {"title": "Service Id", "type": "integer"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "anomaly_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Anomaly Ids"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "PLANNED", "title": "Status"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}}, "required": ["customer_id", "service_id"], "title": "PlanningServiceOrderCreate", "type": "object"}, "PlanningServiceOrderUpdate": {"properties": {"project_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Project Id"}, "service_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Id"}, "vendor_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Vendor Id"}, "location_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Location Id"}, "turbine_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Id"}, "turbine_component_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Turbine Component Id"}, "anomaly_ids": {"anyOf": [{"items": {"type": "integer"}, "type": "array"}, {"type": "null"}], "title": "Anomaly Ids"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "priority": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Priority"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "notes": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Notes"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "actual_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual Start Date"}, "actual_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Actual End Date"}, "planned_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Planned Cost"}, "actual_cost": {"anyOf": [{"type": "number"}, {"type": "string"}, {"type": "null"}], "title": "Actual Cost"}}, "title": "PlanningServiceOrderUpdate", "type": "object"}, "PlanningWorkOrderTypeQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}}, "title": "PlanningWorkOrderTypeQueryParams", "type": "object"}, "PlanningWorkOrderTypeResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "code", "customer_id", "created_at", "updated_at"], "title": "PlanningWorkOrderTypeResponse", "type": "object"}, "PlanningWorkOrderTypeCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["customer_id", "code"], "title": "PlanningWorkOrderTypeCreate", "type": "object"}, "PlanningWorkOrderTypeUpdate": {"properties": {"code": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Code"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "title": "PlanningWorkOrderTypeUpdate", "type": "object"}, "PlanningWorkOrderQueryParams": {"additionalProperties": false, "properties": {"search": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "sort": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Sort"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "customer_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Customer Id"}, "service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Type Id"}}, "title": "PlanningWorkOrderQueryParams", "type": "object"}, "PlanningNestedServiceOrder": {"properties": {"id": {"title": "Id", "type": "integer"}, "number": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Number"}}, "required": ["id"], "title": "PlanningNestedServiceOrder", "type": "object"}, "PlanningNestedWorkOrderType": {"properties": {"id": {"title": "Id", "type": "integer"}, "code": {"title": "Code", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "required": ["id", "code"], "title": "PlanningNestedWorkOrderType", "type": "object"}, "PlanningWorkOrderResponse": {"properties": {"id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"title": "Status", "type": "string"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "position": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Position"}, "custom_fields": {"default": [], "items": {}, "title": "Custom Fields", "type": "array"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source"}, "customer_id": {"title": "Customer Id", "type": "integer"}, "customer": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedCustomer"}, {"type": "null"}]}, "service_order_id": {"title": "Service Order Id", "type": "integer"}, "service_order": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedServiceOrder"}, {"type": "null"}]}, "type_id": {"title": "Type Id", "type": "integer"}, "type": {"anyOf": [{"$ref": "#/components/schemas/PlanningNestedWorkOrderType"}, {"type": "null"}]}, "created_at": {"format": "date-time", "title": "Created At", "type": "string"}, "updated_at": {"format": "date-time", "title": "Updated At", "type": "string"}}, "required": ["id", "name", "status", "customer_id", "service_order_id", "type_id", "created_at", "updated_at"], "title": "PlanningWorkOrderResponse", "type": "object"}, "PlanningWorkOrderCreate": {"additionalProperties": false, "properties": {"customer_id": {"title": "Customer Id", "type": "integer"}, "service_order_id": {"title": "Service Order Id", "type": "integer"}, "type_id": {"title": "Type Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "PLANNED", "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "position": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Position"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Custom Fields"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source"}}, "required": ["customer_id", "service_order_id", "type_id", "name"], "title": "PlanningWorkOrderCreate", "type": "object"}, "PlanningWorkOrderUpdate": {"properties": {"service_order_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Service Order Id"}, "type_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Type Id"}, "name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Name"}, "status": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "planned_start_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned Start Date"}, "planned_end_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Planned End Date"}, "completed_date": {"anyOf": [{"format": "date", "type": "string"}, {"type": "null"}], "title": "Completed Date"}, "position": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Position"}, "custom_fields": {"anyOf": [{"items": {}, "type": "array"}, {"type": "null"}], "title": "Custom Fields"}, "source": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Source"}}, "title": "PlanningWorkOrderUpdate", "type": "object"}, "PlanningStatusOption": {"additionalProperties": false, "properties": {"value": {"title": "Value", "type": "string"}, "label": {"title": "Label", "type": "string"}, "color": {"title": "Color", "type": "string"}}, "required": ["value", "label", "color"], "title": "PlanningStatusOption", "type": "object"}, "PlanningStatusesResponse": {"additionalProperties": false, "description": "Authoritative planning status catalogue, one list per entity.\n\nCampaign, Project, ServiceOrder and WorkOrder all share the single unified\n``PlanningStatus`` enum today, so the four lists are identical. The per-entity\nshape is kept so the contract can diverge later without a breaking change.", "properties": {"campaign": {"items": {"$ref": "#/components/schemas/PlanningStatusOption"}, "title": "Campaign", "type": "array"}, "project": {"items": {"$ref": "#/components/schemas/PlanningStatusOption"}, "title": "Project", "type": "array"}, "service_order": {"items": {"$ref": "#/components/schemas/PlanningStatusOption"}, "title": "Service Order", "type": "array"}, "work_order": {"items": {"$ref": "#/components/schemas/PlanningStatusOption"}, "title": "Work Order", "type": "array"}}, "required": ["campaign", "project", "service_order", "work_order"], "title": "PlanningStatusesResponse", "type": "object"}}, "securitySchemes": {"APIKeyAuth": {"type": "http", "scheme": "bearer"}, "CookieAuth": {"type": "apiKey", "in": "cookie", "name": "opshub_prod_sessionid"}, "AuthBearer": {"type": "http", "scheme": "bearer"}}}, "servers": []}